asn1: X.681/682/683 magic handling of open types

Status:

 - And it works!

 - We have an extensive test based on decoding a rich EK certficate.

   This test exercises all of:

    - decoding
    - encoding with and without decoded open types
    - copying of decoded values with decoded open types
    - freeing of decoded values with decoded open types

   Valgrind finds no memory errors.

 - Added a manual page for the compiler.

 - rfc2459.asn1 now has all three primary PKIX types that we care about
   defined as in RFC5912, with IOS constraints and parameterization:

    - `Extension`       (embeds open type in an `OCTET STRING`)
    - `OtherName`       (embeds open type in an        `ANY`-like type)
    - `SingleAttribute` (embeds open type in an        `ANY`-like type)
    - `AttributeSet`    (embeds open type in a  `SET OF ANY`-like type)

   All of these use OIDs as the open type type ID field, but integer
   open type type ID fields are also supported (and needed, for
   Kerberos).

   That will cover every typed hole pattern in all our ASN.1 modules.

   With this we'll be able to automatically and recursively decode
   through all subject DN attributes even when the subject DN is a
   directoryName SAN, and subjectDirectoryAttributes, and all
   extensions, and all SANs, and all authorization-data elements, and
   PA-data, and...

   We're not really using `SingleAttribute` and `AttributeSet` yet
   because various changes are needed in `lib/hx509` for that.

 - `asn1_compile` builds and recognizes the subset of X.681/682/683 that
   we need for, and now use in, rfc2459.asn1.  It builds the necessary
   AST, generates the correct C types, and generates templating for
   object sets and open types!

 - See READMEs for details.

 - Codegen backend not tested; I won't make it implement automatic open
   type handling, but it should at least not crash by substituting
   `heim_any` for open types not embedded in `OCTET STRING`.

 - We're _really_ starting to have problems with the ITU-T ASN.1
   grammar and our version of it...

   Type names have to start with upper-case, value names with
   lower-case, but it's not enough to disambiguate.

   The fact the we've allowed value and type names to violate their
   respective start-with case rules is causing us trouble now that we're
   adding grammar from X.681/682/683, and we're going to have to undo
   that.

   In preparation for that I'm capitalizing the `heim_any` and
   `heim_any_set` types, and doing some additional cleanup, which
   requires changes to other parts of Heimdal (all in this same commit
   for now).

   Problems we have because of this:

    - We cannot IMPORT values into modules because we have no idea if a
      symbol being imported refers to a value or a type because the only
      clue we would have is the symbol's name, so we assume IMPORTed
      symbols are for types.

      This means we can't import OIDs, for example, which is super
      annoying.

      One thing we might be able to do here is mark imported symbols as
      being of an undetermined-but-not-undefined type, then coerce the
      symbol's type the first time it's used in a context where its type
      is inferred as type, value, object, object set, or class.  (Though
      since we don't generate C symbols for objects or classes, we won't
      be able to import them, especially since we need to know them at
      compile time and cannot defer their handling to link- or
      run-time.)

    - The `NULL` type name, and the `NULL` value name now cause two
      reduce/reduce conflicts via the `FieldSetting` production.

    - Various shift/reduce conflicts involving `NULL` values in
      non-top-level contexts (in constraints, for example).

 - Currently I have a bug where to disambiguate the grammar I have a
   CLASS_IDENTIFIER token that is all caps, while TYPE_IDENTIFIER must
   start with a capital but not be all caps, but this breaks Kerberos
   since all its types are all capitalized -- oof!

   To fix this I made it so class names have to be all caps and
   start with an underscore (ick).

TBD:

 - Check all the XXX comments and address them
 - Apply this treatment to Kerberos!  Automatic handling of authz-data
   sounds useful :)
 - Apply this treatment to PKCS#10 (CSRs) and other ASN.1 modules too.
 - Replace various bits of code in `lib/hx509/` with uses of this
   feature.
 - Add JER.
 - Enhance `hxtool` and `asn1_print`.

Getting there!
This commit is contained in:
Nicolas Williams
2021-02-08 22:40:51 -06:00
parent 89f97e8287
commit db7763ca7b
64 changed files with 5076 additions and 850 deletions

View File

@@ -139,9 +139,9 @@ fi
AM_CONDITIONAL(OPENLDAP_MODULE, test "$enable_hdb_openldap_module" = yes -a "$with_openldap" = yes)
AC_ARG_ENABLE(asn1-templating,
AS_HELP_STRING([--enable-asn1-templating],
AS_HELP_STRING([--disable-asn1-templating],
[if you want disable to use of the ASN.1 templating compiler]))
AM_CONDITIONAL(ASN1_TEMPLATING, test "x$enable_asn1_templating" = xyes)
AM_CONDITIONAL(ASN1_TEMPLATING, test "x$enable_asn1_templating" != xno)
dnl
dnl Optional modules, pk-init, digest, kx509

View File

@@ -2255,7 +2255,7 @@ _kdc_as_rep(astgs_request_t r)
copy_HostAddresses(b->addresses, r->et.caddr);
}
r->et.transited.tr_type = DOMAIN_X500_COMPRESS;
r->et.transited.tr_type = domain_X500_Compress;
krb5_data_zero(&r->et.transited.contents);
/* The MIT ASN.1 library (obviously) doesn't tell lengths encoded

View File

@@ -658,7 +658,7 @@ fix_transited_encoding(krb5_context context,
size_t i;
switch (tr->tr_type) {
case DOMAIN_X500_COMPRESS:
case domain_X500_Compress:
break;
case 0:
/*
@@ -744,7 +744,7 @@ fix_transited_encoding(krb5_context context,
}
et->flags.transited_policy_checked = 1;
}
et->transited.tr_type = DOMAIN_X500_COMPRESS;
et->transited.tr_type = domain_X500_Compress;
ret = krb5_domain_x500_encode(realms, num_realms, &et->transited.contents);
if(ret)
krb5_warn(context, ret, "Encoding transited encoding");

View File

@@ -89,7 +89,7 @@ encode_ticket(krb5_context context,
krb5_data empty_string;
krb5_data_zero(&empty_string);
et.transited.tr_type = DOMAIN_X500_COMPRESS;
et.transited.tr_type = domain_X500_Compress;
et.transited.contents = empty_string;
}
et.authtime = cred->times.authtime;

View File

@@ -6,6 +6,8 @@ YFLAGS = -d -t
AM_CPPFLAGS += $(ROKEN_RENAME)
man_MANS = asn1_compile.1
lib_LTLIBRARIES = libasn1.la
libasn1_la_LDFLAGS = -version-info 8:0:0
@@ -23,9 +25,7 @@ libasn1_la_LIBADD = \
BUILT_SOURCES = \
$(gen_files_rfc2459:.x=.c) \
$(gen_files_rfc4043:.x=.c) \
$(gen_files_rfc4108:.x=.c) \
$(gen_files_tcg:.x=.c) \
$(gen_files_cms:.x=.c) \
$(gen_files_krb5:.x=.c) \
$(gen_files_ocsp:.x=.c) \
@@ -42,9 +42,7 @@ gen_files_krb5 = asn1_krb5_asn1.x
gen_files_cms = asn1_cms_asn1.x
gen_files_crmf = asn1_crmf_asn1.x
gen_files_rfc2459 = asn1_rfc2459_asn1.x
gen_files_rfc4043 = asn1_rfc4043_asn1.x
gen_files_rfc4108 = asn1_rfc4108_asn1.x
gen_files_tcg = asn1_tcg_asn1.x
gen_files_ocsp = asn1_ocsp_asn1.x
gen_files_pkinit = asn1_pkinit_asn1.x
gen_files_pkcs10 = asn1_pkcs10_asn1.x
@@ -73,6 +71,7 @@ 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_template:.x=.c)
check_gen_template_CPPFLAGS = -DASN1_IOS_SUPPORTED
dist_check_gen_template_SOURCES = check-gen.c check-common.c check-common.h
nodist_check_gen_template_SOURCES = $(gen_files_test_template:.x=.c)
@@ -154,9 +153,7 @@ check_ber_LDADD = $(check_gen_LDADD)
CLEANFILES = \
$(BUILT_SOURCES) \
$(gen_files_rfc2459) \
$(gen_files_rfc4043) \
$(gen_files_rfc4108) \
$(gen_files_tcg) \
$(gen_files_cms) \
$(gen_files_krb5) \
$(gen_files_ocsp) \
@@ -174,9 +171,7 @@ CLEANFILES = \
asn1parse.c asn1parse.h lex.c \
asn1_err.c asn1_err.h \
rfc2459_asn1_files rfc2459_asn1*.h* rfc2459_asn1*.x \
rfc4043_asn1_files rfc4043_asn1*.h* rfc4043_asn1*.x \
rfc4108_asn1_files rfc4108_asn1*.h* rfc4108_asn1*.x \
tcg_asn1_files tcg_asn1*.h* tcg_asn1*.x \
cms_asn1_files cms_asn1*.h* cms_asn1*.x \
crmf_asn1_files crmf_asn1*.h* crmf_asn1*.x \
krb5_asn1_files krb5_asn1*.h* krb5_asn1*.x \
@@ -203,9 +198,7 @@ nodist_include_HEADERS += pkinit_asn1.h
nodist_include_HEADERS += cms_asn1.h
nodist_include_HEADERS += crmf_asn1.h
nodist_include_HEADERS += rfc2459_asn1.h
nodist_include_HEADERS += rfc4043_asn1.h
nodist_include_HEADERS += rfc4108_asn1.h
nodist_include_HEADERS += tcg_asn1.h
nodist_include_HEADERS += ocsp_asn1.h
nodist_include_HEADERS += pkcs8_asn1.h
nodist_include_HEADERS += pkcs9_asn1.h
@@ -220,9 +213,7 @@ priv_headers += pkinit_asn1-priv.h
priv_headers += cms_asn1-priv.h
priv_headers += crmf_asn1-priv.h
priv_headers += rfc2459_asn1-priv.h
priv_headers += rfc4043_asn1-priv.h
priv_headers += rfc4108_asn1-priv.h
priv_headers += tcg_asn1-priv.h
priv_headers += ocsp_asn1-priv.h
priv_headers += pkcs8_asn1-priv.h
priv_headers += pkcs9_asn1-priv.h
@@ -255,9 +246,7 @@ $(gen_files_pkcs12) pkcs12_asn1.hx pkcs12_asn1-priv.hx: pkcs12_asn1_files
$(gen_files_digest) digest_asn1.hx digest_asn1-priv.hx: digest_asn1_files
$(gen_files_kx509) kx509_asn1.hx kx509_asn1-priv.hx: kx509_asn1_files
$(gen_files_rfc2459) rfc2459_asn1.hx rfc2459_asn1-priv.hx: rfc2459_asn1_files
$(gen_files_rfc4043) rfc4043_asn1.hx rfc4043_asn1-priv.hx: rfc4043_asn1_files
$(gen_files_rfc4108) rfc4108_asn1.hx rfc4108_asn1-priv.hx: rfc4108_asn1_files
$(gen_files_tcg) tcg_asn1.hx tcg_asn1-priv.hx: tcg_asn1_files
$(gen_files_cms) cms_asn1.hx cms_asn1-priv.hx: cms_asn1_files
$(gen_files_crmf) crmf_asn1.hx crmf_asn1-priv.hx: crmf_asn1_files
$(gen_files_x690sample) x690sample_asn1.hx x690sample_asn1-priv.hx: x690sample_asn1_files
@@ -270,19 +259,12 @@ else
TEMPLATE_OPTION=
endif
# XXX Currently using the template compiler for rfc2459.asn1 breaks
rfc2459_asn1_files: asn1_compile$(EXEEXT) $(srcdir)/rfc2459.asn1
$(ASN1_COMPILE) --one-code-file $(TEMPLATE_OPTION) --option-file=$(srcdir)/rfc2459.opt $(srcdir)/rfc2459.asn1 rfc2459_asn1 || (rm -f rfc2459_asn1_files ; exit 1)
rfc4043_asn1_files: asn1_compile$(EXEEXT) $(srcdir)/rfc4043.asn1
$(ASN1_COMPILE) --one-code-file $(TEMPLATE_OPTION) $(srcdir)/rfc4043.asn1 rfc4043_asn1 || (rm -f rfc4043_asn1_files ; exit 1)
rfc4108_asn1_files: asn1_compile$(EXEEXT) $(srcdir)/rfc4108.asn1
$(ASN1_COMPILE) --one-code-file $(TEMPLATE_OPTION) $(srcdir)/rfc4108.asn1 rfc4108_asn1 || (rm -f rfc4108_asn1_files ; exit 1)
tcg_asn1_files: asn1_compile$(EXEEXT) $(srcdir)/tcg.asn1
$(ASN1_COMPILE) --prefix-enum --one-code-file $(TEMPLATE_OPTION) $(srcdir)/tcg.asn1 tcg_asn1 || (rm -f tcg_asn1_files ; exit 1)
cms_asn1_files: asn1_compile$(EXEEXT) $(srcdir)/cms.asn1 $(srcdir)/cms.opt
$(ASN1_COMPILE) --one-code-file $(TEMPLATE_OPTION) --option-file=$(srcdir)/cms.opt $(srcdir)/cms.asn1 cms_asn1 || (rm -f cms_asn1_files ; exit 1)
@@ -348,7 +330,6 @@ EXTRA_DIST = \
pkcs10.asn1 \
pkinit.asn1 \
rfc2459.asn1 \
rfc4043.asn1 \
rfc4108.asn1 \
tcg.asn1 \
setchgpw2.asn1 \

View File

@@ -31,7 +31,7 @@
RELDIR=lib\asn1
intcflags=-I$(SRCDIR) -I$(OBJ) -DROKEN_RENAME
intcflags=-I$(SRCDIR) -I$(OBJ) -DROKEN_RENAME -DASN1_IOS_SUPPORTED
!include ../../windows/NTMakefile.w32
@@ -43,12 +43,8 @@ gen_files_crmf = $(OBJ)\asn1_crmf_asn1.x
gen_files_rfc2459 = $(OBJ)\asn1_rfc2459_asn1.x
gen_files_rfc4043 = $(OBJ)\asn1_rfc4043_asn1.x
gen_files_rfc4108 = $(OBJ)\asn1_rfc4108_asn1.x
gen_files_tcg = $(OBJ)\asn1_tcg_asn1.x
gen_files_ocsp = $(OBJ)\asn1_ocsp_asn1.x
gen_files_pkinit = $(OBJ)\asn1_pkinit_asn1.x
@@ -128,11 +124,8 @@ LIBASN1_OBJS= \
$(OBJ)\extra.obj \
$(OBJ)\timegm.obj \
$(gen_files_rfc2459:.x=.obj) \
$(gen_files_rfc4043:.x=.obj) \
$(gen_files_rfc4108:.x=.obj) \
$(gen_files_tcg:.x=.obj) \
$(gen_files_cms:.x=.obj) \
$(gen_files_crmf:.x=.obj) \
$(gen_files_krb5:.x=.obj) \
$(gen_files_ocsp:.x=.obj) \
$(gen_files_pkinit:.x=.obj) \
@@ -190,12 +183,8 @@ $(gen_files_kx509:.x=.c) : $$(@R).x
$(gen_files_rfc2459:.x=.c) : $$(@R).x
$(gen_files_rfc4043:.x=.c) : $$(@R).x
$(gen_files_rfc4108:.x=.c) : $$(@R).x
$(gen_files_tcg:.x=.c) : $$(@R).x
$(gen_files_cms:.x=.c) : $$(@R).x
$(gen_files_crmf:.x=.c) : $$(@R).x
@@ -209,6 +198,7 @@ $(gen_files_test_template:.x=.c) : $$(@R).x
$(gen_files_krb5) $(OBJ)\krb5_asn1.hx: $(BINDIR)\asn1_compile.exe krb5.asn1 krb5.opt
cd $(OBJ)
$(BINDIR)\asn1_compile.exe \
--template \
--one-code-file \
--option-file=$(SRCDIR)\krb5.opt \
$(SRCDIR)\krb5.asn1 krb5_asn1 \
@@ -218,6 +208,7 @@ $(gen_files_krb5) $(OBJ)\krb5_asn1.hx: $(BINDIR)\asn1_compile.exe krb5.asn1 krb5
$(gen_files_ocsp) $(OBJ)\ocsp_asn1.hx: $(BINDIR)\asn1_compile.exe ocsp.asn1
cd $(OBJ)
$(BINDIR)\asn1_compile.exe \
--template \
--one-code-file \
--option-file=$(SRCDIR)\ocsp.opt \
$(SRCDIR)\ocsp.asn1 \
@@ -227,25 +218,26 @@ $(gen_files_ocsp) $(OBJ)\ocsp_asn1.hx: $(BINDIR)\asn1_compile.exe ocsp.asn1
$(gen_files_pkinit) $(OBJ)\pkinit_asn1.hx: $(BINDIR)\asn1_compile.exe pkinit.asn1
cd $(OBJ)
$(BINDIR)\asn1_compile.exe --one-code-file $(SRCDIR)\pkinit.asn1 pkinit_asn1 \
$(BINDIR)\asn1_compile.exe --template --one-code-file $(SRCDIR)\pkinit.asn1 pkinit_asn1 \
|| ($(RM) $(OBJ)\pkinit_asn1.h ; exit /b 1)
cd $(SRCDIR)
$(gen_files_pkcs8) $(OBJ)\pkcs8_asn1.hx: $(BINDIR)\asn1_compile.exe pkcs8.asn1
cd $(OBJ)
$(BINDIR)\asn1_compile.exe --one-code-file $(SRCDIR)\pkcs8.asn1 pkcs8_asn1 \
$(BINDIR)\asn1_compile.exe --template --one-code-file $(SRCDIR)\pkcs8.asn1 pkcs8_asn1 \
|| ($(RM) $(OBJ)\pkcs8_asn1.h ; exit /b 1)
cd $(SRCDIR)
$(gen_files_pkcs9) $(OBJ)\pkcs9_asn1.hx: $(BINDIR)\asn1_compile.exe pkcs9.asn1
cd $(OBJ)
$(BINDIR)\asn1_compile.exe --one-code-file $(SRCDIR)\pkcs9.asn1 pkcs9_asn1 \
$(BINDIR)\asn1_compile.exe --template --one-code-file $(SRCDIR)\pkcs9.asn1 pkcs9_asn1 \
|| ($(RM) $(OBJ)\pkcs9_asn1.h ; exit /b 1)
cd $(SRCDIR)
$(gen_files_pkcs10) $(OBJ)\pkcs10_asn1.hx: $(BINDIR)\asn1_compile.exe pkcs10.asn1
cd $(OBJ)
$(BINDIR)\asn1_compile.exe \
--template \
--one-code-file \
--option-file=$(SRCDIR)\pkcs10.opt \
$(SRCDIR)\pkcs10.asn1 \
@@ -255,58 +247,45 @@ $(gen_files_pkcs10) $(OBJ)\pkcs10_asn1.hx: $(BINDIR)\asn1_compile.exe pkcs10.asn
$(gen_files_pkcs12) $(OBJ)\pkcs12_asn1.hx: $(BINDIR)\asn1_compile.exe pkcs12.asn1
cd $(OBJ)
$(BINDIR)\asn1_compile.exe --one-code-file $(SRCDIR)\pkcs12.asn1 pkcs12_asn1 \
$(BINDIR)\asn1_compile.exe --template --one-code-file $(SRCDIR)\pkcs12.asn1 pkcs12_asn1 \
|| ($(RM) $(OBJ)\pkcs12_asn1.h ; exit /b 1)
cd $(SRCDIR)
$(gen_files_digest) $(OBJ)\digest_asn1.hx: $(BINDIR)\asn1_compile.exe digest.asn1
cd $(OBJ)
$(BINDIR)\asn1_compile.exe --one-code-file $(SRCDIR)\digest.asn1 digest_asn1 \
$(BINDIR)\asn1_compile.exe --template --one-code-file $(SRCDIR)\digest.asn1 digest_asn1 \
|| ($(RM) $(OBJ)\digest_asn1.h ; exit /b 1)
cd $(SRCDIR)
$(gen_files_kx509) $(OBJ)\kx509_asn1.hx: $(BINDIR)\asn1_compile.exe kx509.asn1
cd $(OBJ)
$(BINDIR)\asn1_compile.exe --one-code-file $(SRCDIR)\kx509.asn1 kx509_asn1 \
$(BINDIR)\asn1_compile.exe --template --one-code-file $(SRCDIR)\kx509.asn1 kx509_asn1 \
|| ($(RM) $(OBJ)\kx509_asn1.h ; exit /b 1)
cd $(SRCDIR)
$(gen_files_rfc2459) $(OBJ)\rfc2459_asn1.hx: $(BINDIR)\asn1_compile.exe rfc2459.asn1
cd $(OBJ)
$(BINDIR)\asn1_compile.exe \
--template \
--one-code-file \
--option-file=$(SRCDIR)\rfc2459.opt \
$(SRCDIR)\rfc2459.asn1 rfc2459_asn1 \
|| ($(RM) $(OBJ)\rfc2459_asn1.h ; exit /b 1)
cd $(SRCDIR)
$(gen_files_rfc4043) $(OBJ)\rfc4043_asn1.hx: $(BINDIR)\asn1_compile.exe rfc4043.asn1
cd $(OBJ)
$(BINDIR)\asn1_compile.exe \
--one-code-file \
$(SRCDIR)\rfc4043.asn1 rfc4043_asn1 \
|| ($(RM) $(OBJ)\rfc4043_asn1.h ; exit /b 1)
cd $(SRCDIR)
$(gen_files_rfc4108) $(OBJ)\rfc4108_asn1.hx: $(BINDIR)\asn1_compile.exe rfc4108.asn1
cd $(OBJ)
$(BINDIR)\asn1_compile.exe \
--template \
--one-code-file \
$(SRCDIR)\rfc4108.asn1 rfc4108_asn1 \
|| ($(RM) $(OBJ)\rfc4108_asn1.h ; exit /b 1)
cd $(SRCDIR)
$(gen_files_tcg) $(OBJ)\tcg_asn1.hx: $(BINDIR)\asn1_compile.exe tcg.asn1
cd $(OBJ)
$(BINDIR)\asn1_compile.exe \
--one-code-file \
$(SRCDIR)\tcg.asn1 tcg_asn1 \
|| ($(RM) $(OBJ)\tcg_asn1.h ; exit /b 1)
cd $(SRCDIR)
$(gen_files_cms) $(OBJ)\cms_asn1.hx: $(BINDIR)\asn1_compile.exe cms.asn1 cms.opt
cd $(OBJ)
$(BINDIR)\asn1_compile.exe \
--template \
--one-code-file --option-file=$(SRCDIR)\cms.opt \
$(SRCDIR)\cms.asn1 cms_asn1 \
|| ($(RM) $(OBJ)\cms_asn1.h ; exit /b 1)
@@ -315,6 +294,7 @@ $(gen_files_cms) $(OBJ)\cms_asn1.hx: $(BINDIR)\asn1_compile.exe cms.asn1 cms.opt
$(gen_files_crmf) $(OBJ)\crmf_asn1.hx: $(BINDIR)\asn1_compile.exe crmf.asn1 crmf.opt
cd $(OBJ)
$(BINDIR)\asn1_compile.exe \
--template \
--one-code-file --option-file=$(SRCDIR)\crmf.opt \
$(SRCDIR)\crmf.asn1 crmf_asn1 \
|| ($(RM) $(OBJ)\crmf_asn1.h ; exit /b 1)
@@ -323,6 +303,7 @@ $(gen_files_crmf) $(OBJ)\crmf_asn1.hx: $(BINDIR)\asn1_compile.exe crmf.asn1 crmf
$(gen_files_x690sample) $(OBJ)\x690sample_asn1.hx: $(BINDIR)\asn1_compile.exe x690sample.asn1
cd $(OBJ)
$(BINDIR)\asn1_compile.exe \
--template \
--one-code-file \
$(SRCDIR)\x690sample.asn1 x690sample_asn1 \
|| ($(RM) $(OBJ)\x690sample_asn1.h ; exit /b 1)
@@ -331,6 +312,7 @@ $(gen_files_x690sample) $(OBJ)\x690sample_asn1.hx: $(BINDIR)\asn1_compile.exe x6
$(gen_files_test) $(OBJ)\test_asn1.hx: $(BINDIR)\asn1_compile.exe test.asn1
cd $(OBJ)
$(BINDIR)\asn1_compile.exe \
--template \
--one-code-file --sequence=TESTSeqOf \
$(SRCDIR)\test.asn1 test_asn1 \
|| ($(RM) $(OBJ)\test_asn1.h ; exit /b 1)
@@ -339,6 +321,7 @@ $(gen_files_test) $(OBJ)\test_asn1.hx: $(BINDIR)\asn1_compile.exe test.asn1
$(gen_files_test_template) $(OBJ)\test_template_asn1.hx: $(BINDIR)\asn1_compile.exe test.asn1
cd $(OBJ)
$(BINDIR)\asn1_compile.exe \
--template \
--one-code-file --template \
--sequence=TESTSeqOf \
$(SRCDIR)\test.asn1 test_template_asn1 \
@@ -370,9 +353,7 @@ GENINCFILES= \
$(INCDIR)\pkcs10_asn1.h \
$(INCDIR)\pkinit_asn1.h \
$(INCDIR)\rfc2459_asn1.h \
$(INCDIR)\rfc4043_asn1.h \
$(INCDIR)\rfc4108_asn1.h \
$(INCDIR)\tcg_asn1.h \
$(INCDIR)\x690sample_asn1.h \
$(OBJ)\krb5_asn1-priv.h \
$(OBJ)\ocsp_asn1-priv.h \
@@ -380,9 +361,7 @@ GENINCFILES= \
$(OBJ)\cms_asn1-priv.h \
$(OBJ)\crmf_asn1-priv.h \
$(OBJ)\rfc2459_asn1-priv.h \
$(OBJ)\rfc4043_asn1-priv.h \
$(OBJ)\rfc4108_asn1-priv.h \
$(OBJ)\tcg_asn1-priv.h \
$(OBJ)\x690sample_asn1-priv.h \
$(OBJ)\pkcs8_asn1-priv.h \
$(OBJ)\pkcs9_asn1-priv.h \
@@ -437,7 +416,6 @@ clean::
TEST_BINARIES=\
$(OBJ)\check-der.exe \
$(OBJ)\check-gen.exe \
$(OBJ)\check-gen-template.exe \
$(OBJ)\check-timegm.exe \
$(OBJ)\check-ber.exe \
@@ -448,7 +426,6 @@ test-binaries: $(TEST_BINARIES)
test-run:
cd $(OBJ)
-check-der.exe
-check-gen.exe
-check-gen-template.exe
-check-timegm.exe
-check-ber.exe
@@ -470,11 +447,6 @@ $(OBJ)\check-der.exe: $(OBJ)\check-der.obj $(OBJ)\check-common.obj \
$(EXECONLINK)
$(EXEPREP_NODIST)
$(OBJ)\check-gen.exe: $(OBJ)\check-gen.obj $(OBJ)\check-common.obj \
$(LIBHEIMDAL) $(LIBROKEN) $(gen_files_test:.x=.obj)
$(EXECONLINK)
$(EXEPREP_NODIST)
$(OBJ)\check-gen-template.exe: $(OBJ)\check-gen.obj $(OBJ)\check-common.obj \
$(LIBHEIMDAL) $(LIBROKEN) $(gen_files_test_template:.x=.obj)
$(EXECONLINK)

View File

@@ -1,4 +1,4 @@
# Bringing the Magical Power of X.681 (ASN.1 Information Object System) to Heimdal
# Automatic Open Type Handling via X.68x Support in Heimdal's ASN.1 Compiler
## Table of Contents
@@ -6,45 +6,62 @@
2. [Typed Holes / Open Types](#typed-holes--open-types)
3. [ASN.1 IOS, Constraint, and Parameterization](#asn1-ios-constraint-and-parameterization)
- [IOS Crash Course](#ios-crash-course)
4. [Implementation Thoughts](#implementation-thoughts)
5. [Moving From C](#moving-from-c)
4. [Usage](#Usage)
5. [Limitations](#Limitations)
6. [Implementation Design](#implementation-design)
7. [Moving From C](#moving-from-c)
## Introduction
The base of ASN.1 is specified by X.680, an ITU-T standard.
ASN.1 is a set of specifications for "syntax" for defining data schemas, and
"encoding rules" for encoding values of data of types defined in those schemas.
There are many encoding rules, but one syntax.
Various extensions are specified in other X.680 series documents:
The base of ASN.1 _syntax_ is specified by X.680, an ITU-T standard. The
encoding rules are specified by the X.69x series (X.690 through X.697).
This README is concerned primarily with the X.68x series.
While X.680 is essential for implementing many Internet (and other) protocols,
and sufficient for implementing all of those, there are extensions in the
remainder of the X.68x series that can make life a lot easier for developers
who have to use ASN.1 for interoperability reasons.
Various syntax extensions are specified in X.68x series documents:
- X.681: Information Object specification
- X.682: Constraint specification
- X.683: Parameterization of ASN.1 specifications
While X.680 is essential for implementing many Internet (and other) protocols,
and sufficient for implementing all of those, implementing a subset of X.681,
X.682, and X.683, can enable some magical features. These magical features are
generally not the focus of those ITU-T specifications nor of many RFCs that
make use of them.
The intent of X.681, X.682, and X.683 is to add ways to formally express
constraints that would otherwise require natural language to express. Give a
compiler more formally-expressed constraints and it can do more labor-saving
than it could otherwise.
This README will cover some ideas for what this magic will be, and
implementation of it.
A subset of these three extensions, X.681, X.682, and X.683, can enable some
rather magical features. These magical features are generally not the focus of
those ITU-T specifications nor of many RFCs that make use of them, but
nonetheless they are of interest to us.
This README covers some ideas for what this magic is, and implementation of it.
RFC 6025 does an excellent job of elucidating X.681, which otherwise most
readers unfamiliar with it will no doubt find inscrutable. Hopefully this
README improces that further.
README improves that further.
The magic that we're after is simply the *automatic and recursive handling of
open types by an ASN.1 compiler*.
Combined with future support for the ASN.1 JSON Encoding Rules (JER) [X.697],
the automatic handling of open types should allow us to trivially implement a
command-line tool that can parse any DER or JER (JSON) encoding of any value
whose type is known and compiled, and which could transcode to the other
encoding rules. I.e., dump DER to JSON, and parse JSON to output DER.
Combined with eventual support for the ASN.1 JSON Encoding Rules (JER) [X.697],
this feature could give us unprecendented visibility into really complex data
structures, such as Endorsement Key Certificates (EKcerts) for Trusted Platform
Module (TPM) applications.
Support for JER and automatic handling of open types should allow us to
trivially implement a command-line tool that can parse any DER or JER (JSON)
encoding of any value whose type is known and compiled, and which could
transcode to the other encoding rules. I.e., dump DER to JSON, and parse JSON
to output DER.
Combined with transcoders for JSON/CBOR and other binary-JSON formats, we could
support those encodings too.
@@ -113,12 +130,16 @@ has typed holes, see SSHv2.
In ASN.1 these generally look like:
```ASN.1
TypedHole ::= SEQUENCE { typeId INTEGER, hole OCTET STRING }
TypedHole ::= SEQUENCE {
typeId INTEGER,
opaque OCTET STRING
}
```
or
```ASN.1
-- Old ASN.1 style
TypedHole ::= SEQUENCE {
typeId OBJECT IDENTIFIER,
opaque ANY DEFINED BY typeID
@@ -128,6 +149,7 @@ or
or
```ASN.1
-- Old ASN.1 style
TypedHole ::= SEQUENCE {
typeId OBJECT IDENTIFIER,
opaque ANY -- DEFINED BY typeID
@@ -208,9 +230,9 @@ Compare this to the handling of discriminated unions (what ASN.1 calls a
The ASN.1 encoding on the wire of a `CHOICE` value, almost no matter the
encoding rules, looks... remarkably like the encoding of a typed hole. Though
generally the alternatives of a discriminated union have to all be encoded with
the same encoding rules, whereas with typed holes the encoded data could
conceivably be encoded in radically different encoding rules than the structure
containing it in a typed hole.
the same encoding rules, whereas with typed holes the encoded data could be
encoded in radically different encoding rules than the structure containing it
in a typed hole.
In fact, extensible `CHOICE`s are handled by our compiler as a discriminated
union one of whose alternatives is a typed hole when the `CHOICE` is
@@ -328,7 +350,8 @@ RFC5912 has lots of examples, such as this `CLASS` corresponding to the
SEQUENCE SIZE (1..MAX) OF Extension{{ExtensionSet}}
```
and these uses of it in RFC5280 (PKIX base):
and these uses of it in RFC5280 (PKIX base) where the actual parameter is
given:
```ASN.1
-- Here we have an individual "object" specifying that the OID
@@ -361,7 +384,7 @@ and these uses of it in RFC5280 (PKIX base):
-- Lastly, we have a Certificate, and the place where the Extensions type's
-- actual parameter is specified.
--
-- This is where the *rubber meets the road*!
-- This is where the rubber meets the road:
Certificate ::= SIGNED{TBSCertificate}
@@ -391,74 +414,96 @@ and these uses of it in RFC5280 (PKIX base):
```
Notice that the `extensions` field of `TBSCertificate` is of type `Extensions`
parametrized by the `CertExtensions` information object set.
parametrized by the `CertExtensions` "information object set".
This allows the compiler to know that if any of the OIDs listed in the
`CertExtensions` object set appear as the actual value of the `extnID` member
of an `Extension` value, then the `extnValue` member of the same `Extension`
value must be an instance of the type associated with that OID. For example,
an `Extension` with `extnID == id-ce-authorityKeyIdentifier` must have an
`extnValue` of type `AuthorityKeyIdentifier`.
an `Extension` with `extnID` value of `id-ce-authorityKeyIdentifier` must have
an `extnValue` of type `AuthorityKeyIdentifier`.
### IOS Crash Course
The ASN.1 IOS is... a bit difficult to understand. X.681 has a lot of strange
terminology, like "variable type value set field". An IOS "class" has fields,
and those fields are of kind `[Fixed]Type[Value[Set]]` or `Object[Set]`.
The ASN.1 IOS may be... a bit difficult to understand -- the syntax isn't
pretty. And X.681 has a lot of strange terminology, like "variable type value
set field".
Classes can have "object sets" associated with them, and each object set has
zero, one, or more "objects". Each object has settings for all required fields
of a class, and possibly also for optional/defaulted fields as well.
An IOS "class" has fields, and those fields are of kind
`[Fixed]Type[Value[Set]]` or `Object[Set]`. Then there's "objects" and "object
sets". Hopefully this section will make all of that comprehensible.
IOS object sets really are akin to relational database tables, while objects
are akin to rows of the same, with columns specified by classes. Or one can
think of classes as tables with one predefined column naming object sets, rows
being objects grouped into oject sets by that column. IOS supports complex
path expressions across these objects (but we won't need that yet).
_Classes_ have fields of various kinds. More on this below.
These relational entities are constant in that they are defined in ASN.1
modules that are compiled. There is no way to change them at run-time, only
query them. They also have no on-the-wire representation.
_Classes_ can also have zero, one, or more _object sets_ associated with them,
and each object set has zero, one, or more _objects_ that are also themselves
associated with classes. Each object has a setting for each required field of
a class, and possibly also for optional/defaulted fields as well.
As X.681 explains, IOS object sets really are akin to relational database
tables, while objects are akin to rows of the same, with columns specified by
classes.
Or one can think of _classes_ as relational tables with one predefined column
naming object sets, and rows being objects grouped into object sets by that
column. IOS supports complex path expressions across these objects (but we
won't need to support that yet).
These relational entities are immutable in that they are defined in ASN.1
modules that are compiled and there is no way to change them at run-time, only
query them. To mutate them one must edit the ASN.1 module that defines them
and recompile it. IOS entities also have no on-the-wire representation.
So far, the IOS seems just so useless to us: we have some, but non-urgent need
to specify constant relational data.
to specify immutable relational data. For example, cryptosystem parameters,
which PKIX does define using IOS, but again: not urgent.
The magic for us lies in being able to document and constrain actual datatypes
using the IOS. We want to use classes and object sets to constrain `SET` or
`SEQUENCE` types (well, really, just `SEQUENCE`) so that our ASN.1 compiler can
have the metadata it needs in ordr to auto-generate decoding and encoding of
values of open types.
using the IOS [X.681], constraint specification [X.682], and type
parameterization [X.683]. We can express the following things:
A termnology point: `SET` and `SEQUENCE` types have "members", but classes and
objects have "fields".
- that some _member_ of a `SET` or `SEQUENCE` is of open type
Objects of a class have all the required fields of a class and any of the
`OPTIONAL` or `DEFAULT` fields of the class. This is very similar to
`SET`/`SEQUENCE` members, which can be `OPTIONAL` or `DEFAULT`ed.
- that some _member_ of a `SET` or `SEQUENCE` identifies a type encoded into
an open type member of the same (or related) `SET` or `SEQUENCE`
The "members" (we call them fields in C, instance variables in C++, Java, ...)
- what pairs of `{type ID value, type}` are allowed for some `SET`'s or
`SEQUENCE`'s open type members
With this our ASN.1 compiler can have the metadata it needs in order to
auto-generate decoding and encoding of values of open types.
A termnology point: `CHOICE`, `SET`, and `SEQUENCE` types have "members", but
_classes_ and _objects_ have "fields", and _object sets_ have elements.
Objects have _settings_ for all the required fields of the object's class and
none, some, or all of the `OPTIONAL` or `DEFAULT` fields of the class. This is
very similar to `SET`/`SEQUENCE` members, which can be `OPTIONAL` or
`DEFAULT`ed.
The _members_ (we call them fields in C, instance variables in C++, Java, ...)
of a `SET` or `SEQUENCE` type are typed, just as in C, C++, Java, etc. for
struct or object types.
There are several kinds of fields of classes. These can be confusing, so it's
essential that we explain them by reference to how they relate to the members
of `SEQUENCE` types constrained by object sets:
There are several kinds of fields of classes. These can be confusing, so it is
useful that we explain them by reference to how they relate to the members of
`SEQUENCE` types constrained by object sets:
- A `type field` of a class is one that specifies a SET or SEQUENCE member of
unknown (open) type.
- A `type field` of a class is one that specifies a `SET` or `SEQUENCE` member
of unknown (i.e., open) type.
The type of that SET or SEQUENCE member will not be not truly unknown, but
determined by some other member of the SET or SEQUENCE, and that will be
The type of that `SET` or `SEQUENCE` member will not be not truly unknown,
but determined by some other member of the SET or SEQUENCE, and that will be
specified in a "value field" (or "value set" field) an "object" in an
"object set" of that class.
This is essentially a "type variable", as is seen in high-level languages
like Haskell.
This is essentially a "type variable", akin to those seen in high-level
languages like Haskell.
- A `fixed type value field` of a class is one that specifies a SET or
SEQUENCE member of fixed type. Being of fixed-type, this is not a type
variable.
variable, naturally.
- A `fixed type value set field` of a class is like a `fixed type value
field`, but where object sets should provide a set of values with which to
@@ -470,17 +515,18 @@ of `SEQUENCE` types constrained by object sets:
- An `object field` will be a field that names another class (possibly the
same class), which can be used to provide rich hierarchical type semantics
that... we don't need for PKIX.
that... we mostly don't need for now.
These define relations between classes, much like `FOREIGN KEY`s in SQL.
These are also known as `link fields`.
- Similarly for `object set field`s.
As usual for ASN.1, the case of the first letter of a field name is meaningful:
- value and object field names start with a lower case letter;
- type, value set, and object set fields start with an upper-case letter;
- object and object set fields are also known as `link fields`.
- type, value set, and object set fields start with an upper-case letter.
The form of a `fixed type value` field and a `fixed type value set` field is
the same, differing only the case of the first letter of the field name.
@@ -501,18 +547,22 @@ Here's a simple example from PKIX:
}
```
- The `&id` field is a fixed-type value field. It's not a fixed-type value
_set_ field because its identifier (`id`) starts with a lower-case letter.
- The `&id` field of `EXTENSION` is a fixed-type value field. It's not a
fixed-type value _set_ field because its identifier (`id`) starts with a
lower-case letter.
The `&id` field is intended to make the `extnId` member of the `Extension`
`SEQUENCE` type name identify the actual type of the `extnValue` member of
the same `SEQUENCE` type.
The `UNIQUE` keyword tells us there can be only one object with any given
value of this field in any object set of this class.
Note that `UNIQUE` keyword tells us there can be only one object with any
given value of this field in any object set of this class. (There is no way
to specify the equivalent of a multi-column `PRIMARY KEY` from SQL, only
single-column primary/unique keys. Note that the `&id` field is not marked
`OPTIONAL` or `DEFAULT`, which is like saying it's `NOT NULL` in SQL.)
- The `&ExtnType` field is a type field. We can tell because no type is named
in its declaration.
in its declaration!
- The `&Critical` field is a fixed-type value set field. We can tell because
it specifies a type (`BOOLEAN`) and starts with an upper-case letter.
@@ -522,8 +572,7 @@ Here's a simple example from PKIX:
that we know there are only two possible values for a `BOOLEAN` field.
- Ignore the `WITH SYNTAX` clause for now. All it does is specify a
user-friendly butimplementor-hostile syntax for specifying objects for this
class.
user-friendly but implementor-hostile syntax for specifying objects.
Note that none of the `Extension` extensions in PKIX actually specify
`CRITICALITY`/`&Critical`, so... we just don't need fixed-type value set
@@ -571,7 +620,7 @@ for object nor object set fields.
Because
- no objects in object sets of `EXTENSION` in PKIX specify "criticality",
- and no objects in object sets of `ATTRIBUTE` in PKIX specify matching rules,
- and no matching rules are specified in PKIX.
- and no matching rules are specified in PKIX (or maybe just one),
we can drop `MATCHING-RULE` and simplify `ATTRIBUTE` and `EXTENSION` as:
```ASN.1
@@ -679,35 +728,88 @@ import them into projects that have an IOS-capable ASN.1 compiler.
Still, for Heimdal we won't bother with the full power of X.681/X.682/X.683 for
now.
## Usage
## Implementation Thoughts
To use this feature you must use the `--template` and `--one-code-file`
arguments to `asn1_compile`. C types are generated from ASN.1 types as
described above.
Note that failure to decode open type values does not cause decoding to fail
altogether. It is important that applications check for undecoded open types.
Open type decoding failures manifest as `NULL` values for the `u` field of the
decoded open type structures (see above).
For examples of X.681/X.682/X.683 usage, look at `lib/asn1/rfc2459.asn1`.
## Limitations
- Currently no effort is made to check the uniqueness of `UNIQUE` fields of
objects in object sets.
- Currently no effort is made to check that required fields are specified in
objects.
- `AtNotation` is very limited.
- Object set extensibility is not supported.
- Only one formal (and actual) type parameter is supported at this time.
- `TYPE-IDENTIFIER` is not built-in at this time. (But users can define it as
specified.)
- `CLASS` "copying" is not supported at this time.
- Link fields are not supported.
- `Information from objects` constructs are not supported.
- `IMPORTS` of IOS entities are not supported at this time.
- ...
## Implementation Design
NOTE: Much of this is already implemented in the `x68x` branch of
https://github.com/nicowilliams/heimdal.
- The required specifications, X.681, X.682, and X.683, are fairly large and
non-trivial. Perhaps we can implement just the subset of those three that
we need to implement PKIX, just as we already implement just the subset of
X.680 that we need to implement PKIX and Kerberos.
non-trivial. We can implement just the subset of those three that we need
to implement PKIX, just as we already implement just the subset of X.680
that we need to implement PKIX and Kerberos.
For dealing with PKIX, the bare minimum of IOS classes we should want are:
- `ATTRIBUTE` (used for `DN` attributes in RFC5280)
- `EXTENSION` (used for certificate extensions in RFC5280)
- `ATTRIBUTE` (used for `DN` attributes in RFC5280, specifically for the
`SingleAttribute` and `AttributeSet` types, RDNs, and the
`subjectDirectoryAttributes` extension)
- `EXTENSION` (used for `Extension`, i.e., certificate extensions in
RFC5280)
- `TYPE-IDENTIFIER` (used for `OtherName` and for CMS' `Content-Type`)
The minimal subset of X.681, X.682, and X.683 needed to implement those
three is all we need. Eventually we may want to increase that subset so as
to implement other IOS classes from PKIX, such as `DIGEST-ALGORITHM`
three is all we need.
_Eventually_ we may want to increase that subset so as to implement other
IOS classes from PKIX, such as `DIGEST-ALGORITHM`, and to provide object
sets and query functionality for them to applications so that we can use
standard modules to encode information about cryptosystems. But not right
now.
Note that there's no object set specified for OTHER-NAME instances, but we
can create our own, and will. We want magic open type decoding to recurse
can and will create our own. We want magic open type decoding to recurse
all the way down and handle DN attributes, extensions, SANs, policy
qualifiers, the works.
- We'll really want to do this mainly for the template compiler and begin
abandoning the original compiler -- maintaining and developing two compiler
backends is difficult enough, but the template compiler is superior just on
account of emitted code size scaling as `O(N)` instead of `O(M * N)` where
`M` is the number of encoding rules supported and `N` is the number of types
in an ASN.1 module (or all modules).
abandoning the original compiler. The codegen backend should generate the
same C types, but no code for automatic, recursive handling of open types.
Maintaining two compiler backends is difficult enough; adding complex
features beyond X.680 to both is too much work. The template compiler is
simply superior just on account of its output size scaling as `O(N)` instead
of `O(M * N)` where `M` is the number of encoding rules supported and `N` is
the size of an ASN.1 module (or all modules).
- Also, to make the transition to using IOS in-tree, we'll want to keep
existing fields of C structures as generated by the compiler today, only
@@ -715,64 +817,297 @@ now.
encoding/decoding can still work and we can then update Heimdal in-tree
slowly to take advantage of the new magic.
Thus `Extension` should compile to something like:
Below are the C types for the ASN.1 PKIX types we care about, as generated
by the current prototype.
`Extension` should and does compile to something like:
```C
typedef struct Extension {
-- Existing fields:
heim_oid extnID;
int *critical;
heim_octet_string extnValue;
-- New, CHOICE-like fields:
enum Extension_iosnum {
Extension_iosnumunknown = 0, /* when the extnID is unrecognized */
Extension_iosnum_ext_AuthorityKeyIdentifier = 1,
Extension_iosnum_ext_ext-SubjectKeyIdentifier = 2,
...
} _ios_element;
union {
heim_octet_string *_value;
authorityKeyIdentifier AuthorityKeyIdentifier;
subjectKeyIdentifier SubjectKeyIdentifier;
...
} _ios_u;
} Extension;
typedef struct Extension {
heim_oid extnID;
int critical;
heim_octet_string extnValue;
/* NEW: */
struct {
enum {
choice_Extension_iosnumunknown = 0,
choice_Extension_iosnum_id_x509_ce_authorityKeyIdentifier,
choice_Extension_iosnum_id_x509_ce_subjectKeyIdentifier,
choice_Extension_iosnum_id_x509_ce_keyUsage,
choice_Extension_iosnum_id_x509_ce_privateKeyUsagePeriod,
choice_Extension_iosnum_id_x509_ce_certificatePolicies,
choice_Extension_iosnum_id_x509_ce_policyMappings,
choice_Extension_iosnum_id_x509_ce_subjectAltName,
choice_Extension_iosnum_id_x509_ce_issuerAltName,
choice_Extension_iosnum_id_x509_ce_basicConstraints,
choice_Extension_iosnum_id_x509_ce_nameConstraints,
choice_Extension_iosnum_id_x509_ce_policyConstraints,
choice_Extension_iosnum_id_x509_ce_extKeyUsage,
choice_Extension_iosnum_id_x509_ce_cRLDistributionPoints,
choice_Extension_iosnum_id_x509_ce_inhibitAnyPolicy,
choice_Extension_iosnum_id_x509_ce_freshestCRL,
choice_Extension_iosnum_id_pkix_pe_authorityInfoAccess,
choice_Extension_iosnum_id_pkix_pe_subjectInfoAccess,
} element;
union {
AuthorityKeyIdentifier* ext_AuthorityKeyIdentifier;
SubjectKeyIdentifier* ext_SubjectKeyIdentifier;
KeyUsage* ext_KeyUsage;
PrivateKeyUsagePeriod* ext_PrivateKeyUsagePeriod;
CertificatePolicies* ext_CertificatePolicies;
PolicyMappings* ext_PolicyMappings;
GeneralNames* ext_SubjectAltName;
GeneralNames* ext_IssuerAltName;
BasicConstraints* ext_BasicConstraints;
NameConstraints* ext_NameConstraints;
PolicyConstraints* ext_PolicyConstraints;
ExtKeyUsage* ext_ExtKeyUsage;
CRLDistributionPoints* ext_CRLDistributionPoints;
SkipCerts* ext_InhibitAnyPolicy;
CRLDistributionPoints* ext_FreshestCRL;
AuthorityInfoAccessSyntax* ext_AuthorityInfoAccess;
SubjectInfoAccessSyntax* ext_SubjectInfoAccessSyntax;
} u;
} _ioschoice_extnValue;
} Extension;
```
The `SingleAttribute` and `AttributeSet` types should and do compile to:
```C
typedef struct SingleAttribute {
heim_oid type;
HEIM_ANY value;
struct {
enum {
choice_SingleAttribute_iosnumunknown = 0,
choice_SingleAttribute_iosnum_id_at_name,
choice_SingleAttribute_iosnum_id_at_surname,
choice_SingleAttribute_iosnum_id_at_givenName,
choice_SingleAttribute_iosnum_id_at_initials,
choice_SingleAttribute_iosnum_id_at_generationQualifier,
choice_SingleAttribute_iosnum_id_at_commonName,
choice_SingleAttribute_iosnum_id_at_localityName,
choice_SingleAttribute_iosnum_id_at_stateOrProvinceName,
choice_SingleAttribute_iosnum_id_at_organizationName,
choice_SingleAttribute_iosnum_id_at_organizationalUnitName,
choice_SingleAttribute_iosnum_id_at_title,
choice_SingleAttribute_iosnum_id_at_dnQualifier,
choice_SingleAttribute_iosnum_id_at_countryName,
choice_SingleAttribute_iosnum_id_at_serialNumber,
choice_SingleAttribute_iosnum_id_at_pseudonym,
choice_SingleAttribute_iosnum_id_domainComponent,
choice_SingleAttribute_iosnum_id_at_emailAddress,
} element;
union {
X520name* at_name;
X520name* at_surname;
X520name* at_givenName;
X520name* at_initials;
X520name* at_generationQualifier;
X520CommonName* at_x520CommonName;
X520LocalityName* at_x520LocalityName;
DirectoryString* at_x520StateOrProvinceName;
DirectoryString* at_x520OrganizationName;
DirectoryString* at_x520OrganizationalUnitName;
DirectoryString* at_x520Title;
heim_printable_string* at_x520dnQualifier;
heim_printable_string* at_x520countryName;
heim_printable_string* at_x520SerialNumber;
DirectoryString* at_x520Pseudonym;
heim_ia5_string* at_domainComponent;
heim_ia5_string* at_emailAddress;
} u;
} _ioschoice_value;
} SingleAttribute;
```
and
```C
typedef struct AttributeSet {
heim_oid type;
struct AttributeSet_values
{
unsigned int len;
HEIM_ANY* val;
} values;
struct {
enum {
choice_AttributeSet_iosnumunknown = 0,
choice_AttributeSet_iosnum_id_at_name,
choice_AttributeSet_iosnum_id_at_surname,
choice_AttributeSet_iosnum_id_at_givenName,
choice_AttributeSet_iosnum_id_at_initials,
choice_AttributeSet_iosnum_id_at_generationQualifier,
choice_AttributeSet_iosnum_id_at_commonName,
choice_AttributeSet_iosnum_id_at_localityName,
choice_AttributeSet_iosnum_id_at_stateOrProvinceName,
choice_AttributeSet_iosnum_id_at_organizationName,
choice_AttributeSet_iosnum_id_at_organizationalUnitName,
choice_AttributeSet_iosnum_id_at_title,
choice_AttributeSet_iosnum_id_at_dnQualifier,
choice_AttributeSet_iosnum_id_at_countryName,
choice_AttributeSet_iosnum_id_at_serialNumber,
choice_AttributeSet_iosnum_id_at_pseudonym,
choice_AttributeSet_iosnum_id_domainComponent,
choice_AttributeSet_iosnum_id_at_emailAddress,
} element;
unsigned int len;
union {
X520name* at_name;
X520name* at_surname;
X520name* at_givenName;
X520name* at_initials;
X520name* at_generationQualifier;
X520CommonName* at_x520CommonName;
X520LocalityName* at_x520LocalityName;
DirectoryString* at_x520StateOrProvinceName;
DirectoryString* at_x520OrganizationName;
DirectoryString* at_x520OrganizationalUnitName;
DirectoryString* at_x520Title;
heim_printable_string* at_x520dnQualifier;
heim_printable_string* at_x520countryName;
heim_printable_string* at_x520SerialNumber;
DirectoryString* at_x520Pseudonym;
heim_ia5_string* at_domainComponent;
heim_ia5_string* at_emailAddress;
} *val;
} _ioschoice_values;
} AttributeSet;
```
The `OtherName` type should and does compile to:
```C
typedef struct OtherName {
heim_oid type_id;
HEIM_ANY value;
struct {
enum {
choice_OtherName_iosnumunknown = 0,
choice_OtherName_iosnum_id_pkix_on_xmppAddr,
choice_OtherName_iosnum_id_pkix_on_dnsSRV,
choice_OtherName_iosnum_id_pkix_on_hardwareModuleName,
choice_OtherName_iosnum_id_pkix_on_permanentIdentifier,
choice_OtherName_iosnum_id_pkix_on_pkinit_san,
choice_OtherName_iosnum_id_pkix_on_pkinit_ms_san,
} element;
union {
heim_utf8_string* on_xmppAddr;
heim_ia5_string* on_dnsSRV;
HardwareModuleName* on_hardwareModuleName;
PermanentIdentifier* on_permanentIdentifier;
KRB5PrincipalName* on_krb5PrincipalName;
heim_utf8_string* on_pkinit_ms_san;
} u;
} _ioschoice_value;
} OtherName;
```
If a caller to `encode_Certificate()` passes a certificate object with
extensions with `_ioselement == Extension_iosnumunknown`, then the encoder
should use the `extnID` and `extnValue` fields, otherwise it should use the
`_ioselement` and `_iosu` fields and ignore the `extnID` and `extnValue`
fields.
extensions with `_ioselement == choice_Extension_iosnumunknown` (or
whatever, for each open type), then the encoder should use the `extnID` and
`extnValue` fields, otherwise it should use the new `_ioschoice_extnValue`
field and leave `extnID` and `extnValue` cleared. If both are set, the
`extnID` and `extnValue` fields, and also the new `_ioschoice_extnValue`
field, then the encoder will ignore the latter.
In both cases, the `critical` field should get used as-is. The rule should
be that we support *two* special C struct fields for open types: a hole type
ID enum field, and a decoded hole value union. All other fields will map to
either normal (possibly constrained) members of the SET/SEQUENCE.
- Type ID values must get mapped to discrete enum values. We'll want type IDs
to be sorted, too, so that we can binary search the object set's template
when decoding for extra speed. For encoding we'll want to "switch" on the
mapped type ID enum, directly indexing the template for the object set.
- Type ID values get mapped to discrete enum values. Object sets get sorted
by object type IDs, allowing for a binary search when decoding. For
encoding and other case we directly index the object set by the mapped type
ID enum.
- The ASN.1 parser merely builds an AST. That will not change.
- The C header generator remains shared between the two backends.
- The C header generator will remain shared between the two backends.
- SET and SEQUENCE types containing an open type are represented as follows in
their templates.
- Only the template backend will support the ASN.1 IOS. We'll basically
encode a new template for the combination of object set and typed hole
container type. This will come with a header entry indicating how many
items are in the object set, and each item will be one entry pointing to the
template for one particular object in the object set. The template for each
object will identify the type ID and the template for the associated type.
```C
extern const struct asn1_template asn1_CertExtensions[];
/*...*/
const struct asn1_template asn1_Extension_tag__22[] = {
/* 0 */ { 0, sizeof(struct Extension), ((void*)5) },
/* 1 */ { A1_TAG_T(ASN1_C_UNIV, PRIM, UT_OID),
offsetof(struct Extension, extnID),
asn1_AttributeType_tag__1 },
/* 2 */ { A1_OP_DEFVAL | A1_DV_BOOLEAN, ~0, (void*)0 },
/* 3 */ { A1_TAG_T(ASN1_C_UNIV, PRIM, UT_Boolean) | A1_FLAG_DEFAULT,
offsetof(struct Extension, critical),
asn1_Extension_tag_critical_24 },
/* 4 */ { A1_TAG_T(ASN1_C_UNIV, PRIM, UT_OctetString),
offsetof(struct Extension, extnValue),
asn1_Extension_tag_extnValue_25 },
/* NEW: vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv */
/* 5 */ { A1_OP_OPENTYPE_OBJSET | 0 | (2 << 10) | 0,
offsetof(Extension, _ioschoice_extnValue),
asn1_CertExtensions }
};
const struct asn1_template asn1_Extension[] = {
/* 0 */ { 0, sizeof(Extension), ((void*)1) },
/* 1 */ { A1_TAG_T(ASN1_C_UNIV, CONS, UT_Sequence),
0, asn1_Extension_tag__22 }
};
Perhaps we'll inline the objects for locality of reference.
/* NEW: */
const struct asn1_template asn1_CertExtensions[] = {
/*
* Header template entry bearing the count of objects in
* this object set:
*/
/* 0 */ { 0, 0, ((void*)18) },
/*
* Value of object #0 in this set: two entries, one naming
* a type ID field value, and the other naming the type
* that corresponds to that value.
*
* In this case, the first object is for the
* AuthorityKeyIdentifier type as a certificate extension.
*/
/* 1 */ { A1_OP_OPENTYPE_ID, 0,
(const void*)&asn1_oid_id_x509_ce_authorityKeyIdentifier },
/* 2 */ { A1_OP_OPENTYPE, sizeof(AuthorityKeyIdentifier),
(const void*)&asn1_AuthorityKeyIdentifier },
/* Value of object #1 (SubjectKeyIdentifier): */
/* 3 */ { A1_OP_OPENTYPE_ID, 0,
(const void*)&asn1_oid_id_x509_ce_subjectKeyIdentifier },
/* 4 */ { A1_OP_OPENTYPE, sizeof(SubjectKeyIdentifier),
(const void*)&asn1_SubjectKeyIdentifier },
/* 5 */
/* And so on...*/
/* Value of object #17 */
/* 35 */ { A1_OP_OPENTYPE_ID, 0,
(const void*)&asn1_oid_id_pkix_pe_subjectInfoAccess },
/* 36 */ { A1_OP_OPENTYPE, sizeof(SubjectInfoAccessSyntax),
(const void*)&asn1_SubjectInfoAccessSyntax }
};
```
After the template entries for all the normal fields of a struct there will
be an object set reference entry identifying the type ID and open type
fields's entries' indices in the same template. The object set has a header
entry followed by pairs of entries each representing a single object and all
of them representing the object set.
This allows the encoder and decoder to both find the object set quickly,
especially if the objects are sorted by type ID value.
## Moving From C
- Generate a JSON representation of each ASN.1 module
- Generate and output a JSON representation of the compiled ASN.1 module.
- Code codegen/templategen backends in jq or Haskell or whatever
- Code codegen/templategen backends in jq or Haskell or whatever.
- Code template interpreters in &lt;host&gt; language
- Code template interpreters in &lt;host&gt; language.
- Eventually rewrite the compiler itself in Rust or whatever.

192
lib/asn1/README-template.md Normal file
View File

@@ -0,0 +1,192 @@
#Notes on Heimdal's ASN.1 compiler's "template" backend
```bash
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: /'
```
Notes about the template parser:
- assumption: code is large, tables smaller
- size scales better as features as added:
- adding encoding rules, textual value parsers, comparators, and so on, are
just new template interpreter, and generally that means no change to
templates.
- so template sizing scales like `O(M + N)` where `M` is the size of the
modules and `N` is the size of the interpreters
- but codegen sizing scales like `O(M * N)`
- as we add interpreters the size advantage of templates increases
- smaller tables and code, more memory sharing, smaller cache footprint,
should lead to better performance
- templates are shared for encode/decode/free/copy/print interpreters,
whereas none of those operations as generated by the codegen backend
share any code
- very compressible -- we waste a lot of space in `struct asn1_template` on
64-bit systems, and still it's smaller than the code generated by the
codegen backend
Note that the template backend does currently dedup templates, though that
is a quadratic operation that we may eventually have to make optional (right
now it's not a problem).
If we made the `ptr` field a `uint32_t` instead of a pointer, and wrote a
linker for templates, and squeezed out some bits of `tt` and `offset` (we'll
never need even 8 bits for tags, let alone 20!, and we'll never need 32 bits
for struct sizes and field offsets either, maybe not even 16-bits), we could
cut the size of `struct asn1_template` in half.
Also, once we add OER/JER we could have an option to not support TLV ERs and
then drop a lot of the tag-related parts of the minified AST that templates
are, further shrinking the templates.
The smaller the templates, the faster interpreting will be.
- use explicit stack instead of recursion in template interpreter to reduce
stack use and increase speed
The code generated by the codegen backend is also recursive, though the
compiler could inline some calls. Using an explicit stack in an iterative
interpreter would likely be a big win.
- how to generate template based stubs
(Note: it's now the default for Heimdal itself.)
Use the `--template` option to `asn1_compile` to use the template backend,
or leave it off to use the codegen backend.
- the template backend now has more functionality than the codegen backend
- much easier to extend! adding new encoding rules is just adding a few
functions to template.c, one set of length/encode/decode functions per ER,
so we could add OER/PER/XDR/GSER/JER with very little work outside that one
file and gen_template.c (to generate stub functions and possibly slight
alterations to templates) and gen.c (to generate declarations of those stub
functions).
TODO:
- Fuzzing tests
- Performance testing
- ASN1_MALLOC_ENCODE() as a function, replaces encode_ and length_
- Fix SIZE constraits
- Proper implementation of `SET { ... }`
- 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
```

322
lib/asn1/README.md Normal file
View File

@@ -0,0 +1,322 @@
# Heimdal's ASN.1 Compiler
This is a new README, and it's not very rich in contents yet. Be sure to check
out the [README on the template backend](/lib/asn1/README-template.md) and the [README
on automatic open type decoding via X.681/X.682/X.683
annotations](/lib/asn1/README-X681.md).
## Table of Contents
1. [Introduction](#Introduction)
2. [ASN.1 Support in Heimdal](#asn1-support-in-heimdal)
3. [News](#News)
4. [Features](#Features)
5. [Limitations](#Limitations)
6. [Compiler Usage](#Compiler-usage)
7. [Implementation](#implementation)
8. [Moving From C](#moving-from-c)
## Introduction
ASN.1 is a... some would say baroque, perhaps obsolete, archaic even, "syntax"
for expressing data type schemas, and also a set of "encoding rules" (ERs) that
specify many ways to encode values of those types for interchange.
Some ERs are binary, others are textual. Some binary ERs are tag-length-value
(TLV), others have no need for tagging. Some of the ERs are roundly and
rightly disliked, but then there are XER (XML Encoding Rules) and JER (JSON
Encoding Rules) that really illustrate how the syntax and the encoding rules
really are separate and distinct things.
ASN.1 is a wheel that everyone loves to reinvent, and often badly. It's worth
knowing a bit about it before reinventing this wheel badly yet again.
It's also worth pondering that there appears to be ways to map most data
exchange metaschemas and schemas onto others, and therefore too, transliterate
most encodings onto others.
First, an example of the syntax:
```ASN.1
-- This is what a certificate looks like (as in TLS server certificates, or
-- "SSL certs):
Certificate ::= SEQUENCE {
tbsCertificate TBSCertificate,
signatureAlgorithm AlgorithmIdentifier,
signatureValue BIT STRING
}
-- The main body of a certificate is here though:
TBSCertificate ::= SEQUENCE {
version [0] Version DEFAULT 1,
serialNumber CertificateSerialNumber,
signature AlgorithmIdentifier,
issuer Name,
validity Validity,
subject Name,
subjectPublicKeyInfo SubjectPublicKeyInfo,
issuerUniqueID [1] IMPLICIT BIT STRING OPTIONAL,
subjectUniqueID [2] IMPLICIT BIT STRING OPTIONAL,
extensions [3] EXPLICIT Extensions OPTIONAL
}
```
Here we see something akin to a "structure" or "record" with various named
fields of various types. Some of these are optional, which means they can have
no value given in encodings. One is defaulted, which means that if no values
is given in encodings then the default value is intended.
Those `[0]` things are called tags and are decidedly obsolete, along with all
"tag-length-value" (TLV) or "self-describing" encoding rules. Tags appear as
lexical tokens in ASN.1 only because a) in the early 80s TLV encodings were
thought fantastic, and b) automatic tagging wasn't invented and implemented
until it was too late. New ASN.1 modules should never need to have those tags
appear in the syntax.
ASN.1 has a lot of competition, and may even be obsolete. Obsolete
technologies take decades to die out because of the need to interoperate with
the installed base. So even if ASN.1 is obsolete, we find ourselves needing to
implement a large subset of it in order to implement certain important network
protocols.
Encoding rules? There are many:
- JSON Encoding Rules (JER) ([X.697](https://www.itu.int/rec/T-REC-X/recommendation.asp?lang=en&parent=T-REC-X.697))
Use JSON instead of some binary scheme like DER (see below).
- XML Encoding Rules (XER) ([X.693](https://www.itu.int/rec/T-REC-X/recommendation.asp?lang=en&parent=T-REC-X.693))
- Generic String Encoding Rules (GSER) ([RFC2641](https://tools.ietf.org/html/rfc2641))
- Basic, Distinguished, and Canonical Encoding Rules (BER, DER, CER) ([X.690](https://www.itu.int/rec/T-REC-X/recommendation.asp?lang=en&parent=T-REC-X.690)
These are the dreaded tag-length-value encoding rules. They are redundant,
wasteful, and inefficient in spite of being non-textual (i.e., binary)!
The descriptor "tag-length-value" is due to all values being encoded as some
bytes for a "tag", then some bytes for the length of the encoded value, then
the encoded value itself. The body of a structured type (e.g.,
`Certificate`) is itself a concatenation of the TLV encodings of the fields
of that structured type, in order.
DER and CER are alternative canonical forms of BER.
- Packed Encoding Rules (PER) ([X.691](https://www.itu.int/rec/T-REC-X/recommendation.asp?lang=en&parent=T-REC-X.691)) and Octet Encoding Rules (OER) ([X.696](https://www.itu.int/rec/T-REC-X/recommendation.asp?lang=en&parent=T-REC-X.696))
These are a lot like eXternal Data Representation
([XDR](https://tools.ietf.org/html/rfc4506.html)), but with 1-octet
alignment instead of 4-octet alignment.
There is also a meta encoding rule system, the Encoding Control Notation (ECN)
([X.692](https://www.itu.int/rec/T-REC-X/recommendation.asp?lang=en&parent=T-REC-X.692))
intended to be able to express all sorts of kinds of encodings.
Heimdal currently only supports DER for encoding, and DER and BER for decoding,
but soon may support JER as well, and can print values as JSON, though not
compliant with JER.
The syntax itself is specified by
[X.680](https://www.itu.int/rec/T-REC-X/recommendation.asp?lang=en&parent=T-REC-X.680),
with extensions via
[X.681](https://www.itu.int/rec/T-REC-X/recommendation.asp?lang=en&parent=T-REC-X.681),
[X.682](https://www.itu.int/rec/T-REC-X/recommendation.asp?lang=en&parent=T-REC-X.682),
and
[X.683](https://www.itu.int/rec/T-REC-X/recommendation.asp?lang=en&parent=T-REC-X.683),.
## ASN.1 Support in Heimdal
Heimdal contains an implementation of:
- ASN.1
- PKIX
- Kerberos
- misc. Heimdal-specific protocols related to PKIX and Kerberos, such as:
- Online certification authority protocols
- Kerberos KDC replication protocols
- Kerberos administration protocols
PKIX and Kerberos both require ASN.1 and DER support.
For historical reasons many ASN.1-using projects have used hand-rolled codecs
that have proven difficult to implement, maintain, and extend, and, of course,
buggy. Heimdal has its own ASN.1 module compiler and library in order to avoid
the pitfalls of hand-rolled codecs, and to satisfy Heimdal's internal needs.
There are other ASN.1 compilers and libraries out there, of course, but it
would prove difficult to switch compilers as generally ASN.1 compilers lack
sufficient control over generated types and APIs for programming languages.
Heimdal's ASN.1 compiler supports a large subset of X.680, X.681, X.682, and
X.683, as well as a large subset of X.690, with an architecture that should
make it easy to add support for encoding rules other than X.690.
## Features
- Most of X.680 is supported.
- Most of X.690 is supported for decoding, with only DER supported for
encoding.
- Unconstrained integer types have a large integer representation in C that is
not terribly useful in common cases. Range constraints on integer types
cause the compiler to use `int32_t`, `int64_t`, `uint32_t`, and/or
`uint64_t`.
- The Heimdal ASN.1 compiler currently handles a large subset of X.680, and
(in a branch) a small subset of X.681, X.682, and X.683, which manifests as
automatic handling of all open types contained in `SET`/`SEQUENCE` types
that are parameterized with information object sets. This allows all open
types in PKIX certificates, for example, to get decoded automatically no
matter how deeply nested. We use a TCG EK certificate that has eight
certificate extensions, including subject alternative names and subject
directory attributes where the attribute values are not string types, and
all of these things get decoded automatically.
- The template backend dedups templates to save space. This is an O(N^2) kind
of feature that we need to make optional, but it works. (When we implement
JER this will have the side-effect of printing the wrong type names in some
cases because two or more types have the same templates and get deduped.)
...
## Limitations
- When using the template backend, `SET { .. }` types are currently not sorted
by tag as they should be, but if the module author sorts them by hand then
DER will be produced.
- `BMPString` is not supported.
- IA5String is not properly supported -- it's essentially treated as a
`UTF8String` with a different tag. This is true of all the string types.
- Only types can be imported at this time. Without some rototilling we likely
will not be able to import anything other than types, values, and object
sets.
- Only simple value syntax is supported. Structured value syntax is not
supported.
- ...
## Compiler Usage
See the manual page `asn1_compile.1`:
```
ASN1_COMPILE(1) HEIMDAL General Commands Manual ASN1_COMPILE(1)
NAME
asn1_compile — compile ASN.1 modules
SYNOPSIS
asn1_compile [--template] [--prefix-enum] [--enum-prefix=PREFIX]
[--encode-rfc1510-bit-string] [--decode-dce-ber]
[--support-ber] [--preserve-binary=TYPE-NAME]
[--sequence=TYPE-NAME] [--one-code-file] [--gen-name=NAME]
[--option-file=FILE] [--original-order] [--no-parse-units]
[--type-file=C-HEADER-FILE] [--version] [--help]
[FILE.asn1 [NAME]]
DESCRIPTION
asn1_compile Compiles an ASN.1 module into C source code and header
files.
Options supported:
--template
Use the “template” backend instead of the “codegen” backend
(which is the default backend). The template backend generates
“templates” which are akin to bytecode, and which are interpreted
at run-time. The codegen backend generates C code for all func
tions directly, with no template interpretation. The template
backend scales better than the codegen backend because as we add
support for more encoding rules the templates stay mostly the
same, thus scaling linearly with size of module. Whereas the
codegen backend scales linear with the product of module size and
number of encoding rules supported. More importantly, currently
only the template backend supports automatic decoding of open
types via X.681/X.682/X.683 annotations.
--prefix-enum
This option should be removed because ENUMERATED types should
always have their labels prefixed.
--enum-prefix=PREFIX
This option should be removed because ENUMERATED types should
always have their labels prefixed.
--encode-rfc1510-bit-string
Use RFC1510, non-standard handling of “BIT STRING” types.
--decode-dce-ber
--support-ber
--preserve-binary=TYPE-NAME
Generate _save fields in structs to preserve the original
encoding of some sub-value. This is useful for cryptographic
applications to avoid having to re-encode values to check signa
tures, etc.
--sequence=TYPE-NAME
Generate add/remove functions for SET OF and SEQUENCE OF
types.
--one-code-file
Generate a single source code file. Otherwise a separate code
file will be generated for every type.
--gen-name=NAME
Use NAME to form the names of the files generated.
--option-file=FILE
Take additional command-line options from FILE.
--original-order
Attempt to preserve the original order of type definition in the
ASN.1 module. By default the compiler generates types in a topo
logical sort order.
--no-parse-units
Do not generate to-int / from-int functions for enumeration
types.
--type-file=C-HEADER-FILE
Generate an include of the named header file that might be needed
for common type defintions.
--version
--help
HEIMDAL February 22, 2021 HEIMDAL
```
## Implementation
...
## Futures
- Add JER support so we can convert between JER and DER?
- Add XDR support?
- Add OER support?
- Add NDR support?
- Perhaps third parties will contribute more control over generate types?
## Moving From C
- Generate and output a JSON representation of the compiled ASN.1 module.
- Code codegen/templategen backends in jq or Haskell or whatever.
- Code template interpreters in some host language.
- Eventually rewrite the compiler itself in Rust or whatever.

View File

@@ -1,163 +0,0 @@
#!/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
- smaller tables and code, smaller cache footprint, better performance
- how to generate template based stubs:
make check asn1_compile_FLAGS=--template > log
or
./configure --enable-asn1-templating
- pretty much the same as the generate code, except uses tables instead of code
- much easier to extend! adding new encoding rules is just adding a few
functions to template.c, one set of length/encode/decode functions per ER,
so we could add OER/PER/XDR/GSER/JER with very little work outside that one
file and gen_template.c (to generate stub functions) and gen.c (to generate
declarations of those stub functions).
TODO:
- Fuzzing tests
- Performance testing
- ASN1_MALLOC_ENCODE() as a function, replaces encode_ and length_
- Fix SIZE constraits
- Proper implementation of `SET { ... }`
- Compact types that only contain on entry to not having a header.
Or maybe not. We can afford larger template footprint if we can get
more bang for that. For example, if we add type and member names to
the templates, we could have template interpreters that implement JER
(JSON Encoding Rules) and/or GSER (Generic String Encoding Rules),
and it will cost only the size of the new interpreters plust the
extra metadata (type and member names).
Perhaps we could rely on `dladdr()` to find the names of template
data structures and work out the type and member names from that?
But then, making more of those static / stripping them would save us
some of the cost of adding type and member names to the templates.
Using `dladdr()` might be a problem because it's not really portable,
and our implementation in lib/roken for WIN32 does not report a
symbol name, but there is a way to get that in WIN32
(see https://github.com/dlfcn-win32/dlfcn-win32/).
E.g., if we know the name of a template table as
"asn1_TBSCertificate_tag_version_28" then we can work out that it's
for the member named `version` in the type named `TBSCertificate`.
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

View File

@@ -52,6 +52,8 @@ typedef struct heim_bit_string {
typedef struct heim_base_data heim_any;
typedef struct heim_base_data heim_any_set;
typedef struct heim_base_data HEIM_ANY;
typedef struct heim_base_data HEIM_ANY_SET;
#define ASN1_MALLOC_ENCODE(T, B, BL, S, L, R) \
do { \

View File

@@ -38,9 +38,55 @@
#ifndef __TEMPLATE_H__
#define __TEMPLATE_H__
/*
* TBD:
*
* - For OER also encode number of optional/default/extension elements into
* header entry's ptr field, not just the number of entries that follow it
*
* - For JER/GSER/whatver, and probably for not-C-coded template interpreters,
* we'll need to have an entry type for the names of structures and their
* fields.
*
* - For auto open types we need a new opcode, let's call it
* A1_OP_OPENTYPE_OBJSET, and we need to encode into its entry:
* a) the index of the template entry for the type ID field, and
* b) the index of the template entry for the open type field,
* c) 1 bit to indicate whether the object set is sorted by type ID value,
* d) a pointer to the object set's template.
* With that we can then find the struct offsets of those, and also their
* types (since we can find their template entries).
* The object set entries should be encoded into two template entries each:
* one pointing to the value of the type ID field for that object (unless
* the value is an integer, in which case the ptr should be the integer
* value directly), and the other pointing to the template for the type
* identified by the type ID. These will need an opcode each...
* A1_OP_OPENTYPE_ID and A1_OP_OPENTYPE.
* We should also end the object set with an A1_OP_OPENTYPE_OBJSET entry so
* that iterating backwards can be fast. Unless... unless we don't inline
* the object set and its objects but point to the object set's template.
* Also, for extensible object sets we can point to the object set's name,
* and we can then have a function to get an object set template by name,
* one to release that, and one to add an object to the object set (there's
* no need to remove objects from object sets, which helps with thread-
* safety). And then we don't need (c) either.
* The decoder will then not see these entries until after decoding the type
* ID and open type field (as its outer type, so OCTET STRING, BIT STRING,
* or HEIM_ANY) and so it will be able to find those values in the struct at
* their respective offsets.
* The encoder and decoder both need to identify the relevant object in the
* object set, either by linear search or binary search if they are sorted
* by type ID value, then interpret the template for the identified type.
* The encoder needs to place the encoding into the normal location for it
* in the struct, then it can execute the normal template entry for it.
*/
/* header:
* HF flags if not a BIT STRING type
* HBF flags if a BIT STRING type
*
* ptr is count of elements
* offset is size of struct
*/
/* tag:
@@ -49,6 +95,9 @@
* 22..23 class
* 24..27 flags
* 28..31 op
*
* ptr points to template for tagged type
* offset is offset of struct field
*/
/* parse:
@@ -56,11 +105,55 @@
* 12..23 unused
* 24..27 flags
* 28..31 op
*
* ptr is NULL
* offset is ...
*/
/* defval: (next template entry is defaulted)
*
* DV flags (ptr is or points to defval)
*
* ptr is default value or pointer to default value
* offset is all ones
*/
/* name: when it happens at index 1 it's the name of the SET/SEQUENCE/CHOICE
* when it happens at any other index it's the name of the field that the
* next entry deals with
*
* 0..23 unused
* 24..27 flags A1_NM_*
* 28..31 op
*
* ptr is const char * pointer to the name as C string
* offset is all zeros
*/
/* objset:
* 0..9 open type ID entry index
* 10..19 open type entry index
* 20..23 unused
* 24..27 flags A1_OS_*
* 28..31 op
*
* ptr points to object set template
* offset is the offset of the choice struct
*/
/* opentypeid: offset is zero
* ptr points to value if it is not an integer
* ptr is the value if it is an integer
* 0..23 unused
* 24..27 flags A1_OTI_*
* 28..31 op
*/
/* opentype: offset is sizeof C type for this open type choice
* ptr points to template for type choice
* 0..23 unused
* 24..27 flags
* 28..31 op
*/
#define A1_OP_MASK (0xf0000000)
@@ -73,6 +166,10 @@
#define A1_OP_BMEMBER (0x70000000)
#define A1_OP_CHOICE (0x80000000)
#define A1_OP_DEFVAL (0x90000000)
#define A1_OP_OPENTYPE_OBJSET (0xa0000000)
#define A1_OP_OPENTYPE_ID (0xb0000000)
#define A1_OP_OPENTYPE (0xc0000000)
#define A1_OP_NAME (0xd0000000)
#define A1_FLAG_MASK (0x0f000000)
#define A1_FLAG_OPTIONAL (0x01000000)
@@ -105,6 +202,10 @@
#define A1_DV_INTEGER64 0x08
#define A1_DV_UTF8STRING 0x10
#define A1_OS_IS_SORTED (0x01000000)
#define A1_OS_OT_IS_ARRAY (0x02000000)
#define A1_OTI_IS_INTEGER (0x04000000)
struct asn1_template {
uint32_t tt;

135
lib/asn1/asn1_compile.1 Normal file
View File

@@ -0,0 +1,135 @@
.\" Copyright (c) 2019 Kungliga Tekniska Högskolan
.\" (Royal Institute of Technology, Stockholm, Sweden).
.\" 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.
.\"
.\" $Id$
.\"
.Dd February 22, 2021
.Dt ASN1_COMPILE 1
.Os HEIMDAL
.Sh NAME
.Nm asn1_compile
.Nd compile ASN.1 modules
.Sh SYNOPSIS
.Nm
.Bk -words
.Op Fl Fl template
.Op Fl Fl prefix-enum
.Op Fl Fl enum-prefix=PREFIX
.Op Fl Fl encode-rfc1510-bit-string
.Op Fl Fl decode-dce-ber
.Op Fl Fl support-ber
.Op Fl Fl preserve-binary=TYPE-NAME
.Op Fl Fl sequence=TYPE-NAME
.Op Fl Fl one-code-file
.Op Fl Fl gen-name=NAME
.Op Fl Fl option-file=FILE
.Op Fl Fl original-order
.Op Fl Fl no-parse-units
.Op Fl Fl type-file=C-HEADER-FILE
.Op Fl Fl version
.Op Fl Fl help
.Op Ar FILE.asn1 Op Ar NAME
.Ek
.Sh DESCRIPTION
.Nm
Compiles an ASN.1 module into C source code and header files.
.Pp
Options supported:
.Bl -tag -width Ds
.It Fl Fl template
Use the
.Dq template
backend instead of the
.Dq codegen
backend (which is the default backend).
The template backend generates
.Dq templates
which are akin to bytecode, and which are interpreted at
run-time.
The codegen backend generates C code for all functions directly,
with no template interpretation.
The template backend scales better than the codegen backend
because as we add support for more encoding rules the templates
stay mostly the same, thus scaling linearly with size of module.
Whereas the codegen backend scales linear with the product of
module size and number of encoding rules supported.
More importantly, currently only the template backend supports
automatic decoding of open types via X.681/X.682/X.683
annotations.
.It Fl Fl prefix-enum
This option should be removed because ENUMERATED types should
always have their labels prefixed.
.It Fl Fl enum-prefix=PREFIX
This option should be removed because ENUMERATED types should
always have their labels prefixed.
.It Fl Fl encode-rfc1510-bit-string
Use RFC1510, non-standard handling of
.Dq BIT STRING
types.
.It Fl Fl decode-dce-ber
.It Fl Fl support-ber
.It Fl Fl preserve-binary=TYPE-NAME
Generate
.Sq _save
fields in structs to preserve the original encoding of some
sub-value.
This is useful for cryptographic applications to avoid having to
re-encode values to check signatures, etc.
.It Fl Fl sequence=TYPE-NAME
Generate add/remove functions for
.Sq SET OF
and
.Sq SEQUENCE OF
types.
.It Fl Fl one-code-file
Generate a single source code file.
Otherwise a separate code file will be generated for every type.
.It Fl Fl gen-name=NAME
Use
.Ar NAME
to form the names of the files generated.
.It Fl Fl option-file=FILE
Take additional command-line options from
.Ar FILE .
.It Fl Fl original-order
Attempt to preserve the original order of type definition in the
ASN.1 module.
By default the compiler generates types in a topological sort
order.
.It Fl Fl no-parse-units
Do not generate to-int / from-int functions for enumeration
types.
.It Fl Fl type-file=C-HEADER-FILE
Generate an include of the named header file that might be needed
for common type defintions.
.It Fl Fl version
.It Fl Fl help
.El

File diff suppressed because it is too large Load Diff

View File

@@ -2029,6 +2029,256 @@ test_x690sample(void)
return 0;
}
#if ASN1_IOS_SUPPORTED
static int
test_ios(void)
{
unsigned char encoded_sample[] = {
0x30, 0x82, 0x04, 0x8e, 0x30, 0x82, 0x03, 0x76,
0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x14, 0x6a,
0x05, 0x97, 0xba, 0x71, 0xd7, 0xe6, 0xd3, 0xac,
0x0e, 0xdc, 0x9e, 0xdc, 0x95, 0xa1, 0x5b, 0x99,
0x8d, 0xe4, 0x0a, 0x30, 0x0d, 0x06, 0x09, 0x2a,
0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b,
0x05, 0x00, 0x30, 0x55, 0x31, 0x0b, 0x30, 0x09,
0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x43,
0x48, 0x31, 0x1e, 0x30, 0x1c, 0x06, 0x03, 0x55,
0x04, 0x0a, 0x13, 0x15, 0x53, 0x54, 0x4d, 0x69,
0x63, 0x72, 0x6f, 0x65, 0x6c, 0x65, 0x63, 0x74,
0x72, 0x6f, 0x6e, 0x69, 0x63, 0x73, 0x20, 0x4e,
0x56, 0x31, 0x26, 0x30, 0x24, 0x06, 0x03, 0x55,
0x04, 0x03, 0x13, 0x1d, 0x53, 0x54, 0x4d, 0x20,
0x54, 0x50, 0x4d, 0x20, 0x45, 0x4b, 0x20, 0x49,
0x6e, 0x74, 0x65, 0x72, 0x6d, 0x65, 0x64, 0x69,
0x61, 0x74, 0x65, 0x20, 0x43, 0x41, 0x20, 0x30,
0x35, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x38, 0x31,
0x32, 0x31, 0x34, 0x30, 0x30, 0x30, 0x30, 0x30,
0x30, 0x5a, 0x17, 0x0d, 0x32, 0x38, 0x31, 0x32,
0x31, 0x34, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
0x5a, 0x30, 0x00, 0x30, 0x82, 0x01, 0x22, 0x30,
0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82,
0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02,
0x82, 0x01, 0x01, 0x00, 0xcc, 0x14, 0xeb, 0x27,
0xa7, 0x8c, 0xeb, 0x0e, 0xa4, 0x86, 0xfa, 0x2d,
0xf7, 0x83, 0x5f, 0x5f, 0xa8, 0xe9, 0x05, 0xb0,
0x97, 0x01, 0x2b, 0x5b, 0xde, 0x50, 0x38, 0x0c,
0x35, 0x5b, 0x1a, 0x2a, 0x72, 0x1b, 0xbc, 0x3d,
0x08, 0xdd, 0x21, 0x79, 0x6c, 0xdb, 0x23, 0x9f,
0xa9, 0x53, 0x10, 0x65, 0x1b, 0x1b, 0x56, 0xfd,
0x2c, 0xfe, 0x53, 0xc8, 0x73, 0x52, 0xeb, 0xd9,
0x96, 0xe3, 0x32, 0x56, 0x16, 0x04, 0x04, 0xce,
0x93, 0x02, 0xa0, 0x80, 0x66, 0x80, 0x1e, 0x78,
0x6a, 0x2f, 0x86, 0xe1, 0x81, 0xf9, 0x49, 0x96,
0x6f, 0x49, 0x2a, 0x85, 0xb5, 0x8e, 0xaa, 0x4a,
0x6a, 0x8c, 0xb3, 0x69, 0x75, 0x51, 0xbb, 0x23,
0x6e, 0x87, 0xcc, 0x7b, 0xf8, 0xec, 0x13, 0x47,
0x87, 0x1c, 0x91, 0xe1, 0x54, 0x37, 0xe8, 0xf2,
0x66, 0xbf, 0x1e, 0xa5, 0xeb, 0x27, 0x1f, 0xdc,
0xf3, 0x74, 0xd8, 0xb4, 0x7d, 0xf8, 0xbc, 0xe8,
0x9e, 0x1f, 0xad, 0x61, 0xc2, 0xa0, 0x88, 0xcb,
0x40, 0x36, 0xb3, 0x59, 0xcb, 0x72, 0xa2, 0x94,
0x97, 0x3f, 0xed, 0xcc, 0xf0, 0xc3, 0x40, 0xaf,
0xfd, 0x14, 0xb6, 0x4f, 0x04, 0x11, 0x65, 0x58,
0x1a, 0xca, 0x34, 0x14, 0x7c, 0x1c, 0x75, 0x61,
0x70, 0x47, 0x05, 0x8f, 0x7e, 0xd7, 0xd6, 0x03,
0xe0, 0x32, 0x50, 0x80, 0x94, 0xfa, 0x73, 0xe8,
0xb9, 0x15, 0x3d, 0xa3, 0xbf, 0x25, 0x5d, 0x2c,
0xbb, 0xc5, 0xdf, 0x30, 0x1b, 0xa8, 0xf7, 0x4d,
0x19, 0x8b, 0xeb, 0xce, 0x86, 0x04, 0x0f, 0xc1,
0xd2, 0x92, 0x7c, 0x76, 0x57, 0x41, 0x44, 0x90,
0xd8, 0x02, 0xf4, 0x82, 0xf3, 0xeb, 0xf2, 0xde,
0x35, 0xee, 0x14, 0x9a, 0x1a, 0x6d, 0xe8, 0xd1,
0x68, 0x91, 0xfb, 0xfb, 0xa0, 0x2a, 0x18, 0xaf,
0xe5, 0x9f, 0x9d, 0x6f, 0x14, 0x97, 0x44, 0xe5,
0xf0, 0xd5, 0x59, 0xb1, 0x02, 0x03, 0x01, 0x00,
0x01, 0xa3, 0x82, 0x01, 0xa9, 0x30, 0x82, 0x01,
0xa5, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23,
0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x1a, 0xdb,
0x99, 0x4a, 0xb5, 0x8b, 0xe5, 0x7a, 0x0c, 0xc9,
0xb9, 0x00, 0xe7, 0x85, 0x1e, 0x1a, 0x43, 0xc0,
0x86, 0x60, 0x30, 0x42, 0x06, 0x03, 0x55, 0x1d,
0x20, 0x04, 0x3b, 0x30, 0x39, 0x30, 0x37, 0x06,
0x04, 0x55, 0x1d, 0x20, 0x00, 0x30, 0x2f, 0x30,
0x2d, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05,
0x07, 0x02, 0x01, 0x16, 0x21, 0x68, 0x74, 0x74,
0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e,
0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x54,
0x50, 0x4d, 0x2f, 0x72, 0x65, 0x70, 0x6f, 0x73,
0x69, 0x74, 0x6f, 0x72, 0x79, 0x2f, 0x30, 0x59,
0x06, 0x03, 0x55, 0x1d, 0x11, 0x01, 0x01, 0xff,
0x04, 0x4f, 0x30, 0x4d, 0xa4, 0x4b, 0x30, 0x49,
0x31, 0x16, 0x30, 0x14, 0x06, 0x05, 0x67, 0x81,
0x05, 0x02, 0x01, 0x0c, 0x0b, 0x69, 0x64, 0x3a,
0x35, 0x33, 0x35, 0x34, 0x34, 0x44, 0x32, 0x30,
0x31, 0x17, 0x30, 0x15, 0x06, 0x05, 0x67, 0x81,
0x05, 0x02, 0x02, 0x0c, 0x0c, 0x53, 0x54, 0x33,
0x33, 0x48, 0x54, 0x50, 0x48, 0x41, 0x48, 0x43,
0x30, 0x31, 0x16, 0x30, 0x14, 0x06, 0x05, 0x67,
0x81, 0x05, 0x02, 0x03, 0x0c, 0x0b, 0x69, 0x64,
0x3a, 0x30, 0x30, 0x34, 0x39, 0x30, 0x30, 0x30,
0x38, 0x30, 0x67, 0x06, 0x03, 0x55, 0x1d, 0x09,
0x04, 0x60, 0x30, 0x5e, 0x30, 0x17, 0x06, 0x05,
0x67, 0x81, 0x05, 0x02, 0x10, 0x31, 0x0e, 0x30,
0x0c, 0x0c, 0x03, 0x32, 0x2e, 0x30, 0x02, 0x01,
0x00, 0x02, 0x02, 0x00, 0x8a, 0x30, 0x43, 0x06,
0x05, 0x67, 0x81, 0x05, 0x02, 0x12, 0x31, 0x3a,
0x30, 0x38, 0x02, 0x01, 0x00, 0x01, 0x01, 0xff,
0xa0, 0x03, 0x0a, 0x01, 0x01, 0xa1, 0x03, 0x0a,
0x01, 0x00, 0xa2, 0x03, 0x0a, 0x01, 0x00, 0xa3,
0x10, 0x30, 0x0e, 0x16, 0x03, 0x33, 0x2e, 0x31,
0x0a, 0x01, 0x04, 0x0a, 0x01, 0x02, 0x01, 0x01,
0xff, 0xa4, 0x0f, 0x30, 0x0d, 0x16, 0x05, 0x31,
0x34, 0x30, 0x2d, 0x32, 0x0a, 0x01, 0x02, 0x01,
0x01, 0x00, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d,
0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02,
0x05, 0x20, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d,
0x13, 0x01, 0x01, 0xff, 0x04, 0x02, 0x30, 0x00,
0x30, 0x10, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x04,
0x09, 0x30, 0x07, 0x06, 0x05, 0x67, 0x81, 0x05,
0x08, 0x01, 0x30, 0x4a, 0x06, 0x08, 0x2b, 0x06,
0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x3e,
0x30, 0x3c, 0x30, 0x3a, 0x06, 0x08, 0x2b, 0x06,
0x01, 0x05, 0x05, 0x07, 0x30, 0x02, 0x86, 0x2e,
0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x73,
0x65, 0x63, 0x75, 0x72, 0x65, 0x2e, 0x67, 0x6c,
0x6f, 0x62, 0x61, 0x6c, 0x73, 0x69, 0x67, 0x6e,
0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x73, 0x74, 0x6d,
0x74, 0x70, 0x6d, 0x65, 0x6b, 0x69, 0x6e, 0x74,
0x30, 0x35, 0x2e, 0x63, 0x72, 0x74, 0x30, 0x0d,
0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01,
0x01, 0x00, 0x3d, 0x4c, 0x38, 0x1e, 0x5b, 0x4f,
0x1b, 0xcb, 0xe0, 0x9c, 0x63, 0xd5, 0x2f, 0x1f,
0x04, 0x57, 0x0c, 0xae, 0xa1, 0x42, 0xfd, 0x9c,
0xd9, 0x42, 0x04, 0x3b, 0x11, 0xf8, 0xe3, 0xbd,
0xcf, 0x50, 0x00, 0x7a, 0xe1, 0x6c, 0xf8, 0x86,
0x90, 0x13, 0x04, 0x1e, 0x92, 0xcd, 0xd3, 0x28,
0x0b, 0xa4, 0xb5, 0x1f, 0xbb, 0xd4, 0x05, 0x82,
0xed, 0x75, 0x02, 0x19, 0xe2, 0x61, 0xa6, 0x95,
0x09, 0x56, 0x74, 0x85, 0x5a, 0xac, 0xeb, 0x52,
0x0a, 0xda, 0xff, 0x9e, 0x7e, 0x90, 0x84, 0x80,
0xa3, 0x9c, 0xdc, 0xf9, 0x00, 0x46, 0x2d, 0x91,
0x71, 0x96, 0x0f, 0xfe, 0x55, 0xd3, 0xac, 0x49,
0xe8, 0xc9, 0x81, 0x34, 0x1b, 0xbd, 0x2e, 0xfb,
0xcc, 0x25, 0x2a, 0x4c, 0x18, 0xa4, 0xf3, 0xb7,
0xc8, 0x4c, 0xce, 0x42, 0xce, 0x70, 0xa2, 0x08,
0xc8, 0x4d, 0x26, 0x30, 0xa7, 0xab, 0xfb, 0xe7,
0x2d, 0x62, 0x71, 0xe7, 0x5b, 0x9f, 0xf1, 0xc9,
0x71, 0xd2, 0x0e, 0xb3, 0xdb, 0xd7, 0x63, 0xf1,
0xe0, 0x4d, 0x83, 0x4e, 0xaa, 0x69, 0x2d, 0x2e,
0x40, 0x01, 0xbb, 0xf4, 0x73, 0x0a, 0x3e, 0x3f,
0xda, 0x97, 0x11, 0xae, 0x38, 0x65, 0x24, 0xd9,
0x1c, 0x63, 0xbe, 0x0e, 0x51, 0x6d, 0x00, 0xd5,
0xc6, 0x14, 0x1f, 0xcc, 0xf6, 0xc5, 0x39, 0xf3,
0x51, 0x8e, 0x18, 0x00, 0x49, 0x86, 0x5b, 0xe1,
0x6b, 0x69, 0xca, 0xe1, 0xf8, 0xcb, 0x7f, 0xdc,
0x47, 0x4b, 0x38, 0xf7, 0xee, 0x56, 0xcb, 0xe7,
0xd8, 0xa8, 0x9d, 0x9b, 0xa9, 0x9b, 0x65, 0xd5,
0x26, 0x5a, 0xef, 0x32, 0xaa, 0x62, 0x42, 0x6b,
0x10, 0xe6, 0xd7, 0x5b, 0xb8, 0x67, 0x7e, 0xc4,
0x4f, 0x75, 0x5b, 0xbc, 0x28, 0x06, 0xfd, 0x2b,
0x4e, 0x04, 0xbd, 0xf5, 0xd4, 0x42, 0x59, 0xdb,
0xea, 0xa4, 0x2b, 0x6f, 0x56, 0x3d, 0xf7, 0xaa,
0x75, 0x06,
};
heim_octet_string os;
Certificate c0, c1;
size_t i, nknown, size;
int ret;
/*
* Test automatic decoding of open types.
*
* Decode a value that has plenty of open types with values of known
* alternatives in them, then check that we got what we wanted.
*/
ret = decode_Certificate(encoded_sample, sizeof(encoded_sample),
&c0, &size);
if (ret)
return 1;
if (size != sizeof(encoded_sample))
return 1;
ret = copy_Certificate(&c0, &c1);
if (ret)
return 1;
if (!c0.tbsCertificate.extensions || !c1.tbsCertificate.extensions)
return 1;
if (!c0.tbsCertificate.extensions->len ||
c0.tbsCertificate.extensions->len != c1.tbsCertificate.extensions->len)
return 1;
for (i = nknown = 0; i < c0.tbsCertificate.extensions->len; i++) {
if (c0.tbsCertificate.extensions->val[i]._ioschoice_extnValue.element !=
c1.tbsCertificate.extensions->val[i]._ioschoice_extnValue.element)
return 1;
if (c0.tbsCertificate.extensions->val[i]._ioschoice_extnValue.element) {
#if 0
fprintf(stderr, "extension %llu known %u\n",
(unsigned long long)i,
c0.tbsCertificate.extensions->val[i]._ioschoice_extnValue._element);
#endif
nknown++;
}
}
if (!nknown)
return 1;
/*
* Check that this round trips. But note that this attempt to encode will
* ignore the automatically decoded open type values from above because
* their encodings are still present.
*/
ASN1_MALLOC_ENCODE(Certificate, os.data, os.length, &c1, &size, ret);
if (ret)
return 1;
if (os.length != size || size != sizeof(encoded_sample))
return 1;
if (memcmp(os.data, encoded_sample, os.length))
return 1;
der_free_octet_string(&os);
/*
* Test automatic encoding of open types by clearing the encoding of one
* such open type value, forcing the encoder to encode the value from
* before.
*/
der_free_octet_string(&c0.tbsCertificate.extensions->val[0].extnValue);
der_free_oid(&c0.tbsCertificate.extensions->val[0].extnID);
ASN1_MALLOC_ENCODE(Certificate, os.data, os.length, &c0, &size, ret);
if (ret)
return 1;
if (os.length != size || size != sizeof(encoded_sample))
return 1;
if (memcmp(os.data, encoded_sample, os.length))
return 1;
der_free_octet_string(&os);
/*
* Repeat, but with the copy, as this will test that copying data
* structures with decoded open types in them also copies those.
*/
der_free_octet_string(&c1.tbsCertificate.extensions->val[0].extnValue);
der_free_oid(&c1.tbsCertificate.extensions->val[0].extnID);
ASN1_MALLOC_ENCODE(Certificate, os.data, os.length, &c1, &size, ret);
if (ret)
return 1;
if (os.length != size || size != sizeof(encoded_sample))
return 1;
if (memcmp(os.data, encoded_sample, os.length))
return 1;
der_free_octet_string(&os);
/* XXX Test setting some of the _ioschoice_extnValue._element's to 0 */
free_Certificate(&c0);
free_Certificate(&c1);
return 0;
}
#endif
int
main(int argc, char **argv)
{
@@ -2072,5 +2322,9 @@ main(int argc, char **argv)
DO_ONE(test_default);
#if ASN1_IOS_SUPPORTED
DO_ONE(test_ios);
#endif
return ret;
}

View File

@@ -5,7 +5,7 @@ CMS DEFINITIONS ::= BEGIN
IMPORTS CertificateSerialNumber, AlgorithmIdentifier, Name,
Attribute, Certificate, SubjectKeyIdentifier FROM rfc2459
heim_any FROM heim;
HEIM_ANY FROM heim;
id-pkcs7 OBJECT IDENTIFIER ::= { iso(1) member-body(2)
us(840) rsadsi(113549) pkcs(1) pkcs7(7) }
@@ -18,11 +18,11 @@ id-pkcs7-digestedData OBJECT IDENTIFIER ::= { id-pkcs7 5 }
id-pkcs7-encryptedData OBJECT IDENTIFIER ::= { id-pkcs7 6 }
CMSVersion ::= INTEGER {
CMSVersion_v0(0),
CMSVersion_v1(1),
CMSVersion_v2(2),
CMSVersion_v3(3),
CMSVersion_v4(4)
cMSVersion-v0(0),
cMSVersion-v1(1),
cMSVersion-v2(2),
cMSVersion-v3(3),
cMSVersion-v4(4)
}
DigestAlgorithmIdentifier ::= AlgorithmIdentifier
@@ -34,7 +34,7 @@ MessageDigest ::= OCTET STRING
ContentInfo ::= SEQUENCE {
contentType ContentType,
content [0] EXPLICIT heim_any OPTIONAL -- DEFINED BY contentType
content [0] EXPLICIT HEIM_ANY OPTIONAL -- DEFINED BY contentType
}
EncapsulatedContentInfo ::= SEQUENCE {
@@ -42,7 +42,7 @@ EncapsulatedContentInfo ::= SEQUENCE {
eContent [0] EXPLICIT OCTET STRING OPTIONAL
}
CertificateSet ::= SET OF heim_any
CertificateSet ::= SET OF HEIM_ANY
CertificateList ::= Certificate

View File

@@ -12,7 +12,7 @@ IMPORTS
Extension,
AlgorithmIdentifier
FROM rfc2459
heim_any
HEIM_ANY
FROM heim;
CRMFRDNSequence ::= SEQUENCE OF RelativeDistinguishedName
@@ -56,7 +56,7 @@ POPOPrivKey ::= CHOICE {
subsequentMessage [1] IMPLICIT SubsequentMessage,
dhMAC [2] BIT STRING, -- Deprecated
agreeMAC [3] IMPLICIT PKMACValue,
encryptedKey [4] heim_any
encryptedKey [4] HEIM_ANY
}
ProofOfPossession ::= CHOICE {
@@ -71,7 +71,7 @@ CertTemplate ::= SEQUENCE {
serialNumber [1] INTEGER OPTIONAL,
signingAlg [2] SEQUENCE {
algorithm OBJECT IDENTIFIER,
parameters heim_any OPTIONAL
parameters HEIM_ANY OPTIONAL
} -- AlgorithmIdentifier -- OPTIONAL,
issuer [3] IMPLICIT CHOICE {
rdnSequence CRMFRDNSequence

View File

@@ -66,7 +66,7 @@ static const char *tag_names[] = {
NULL, /* 9 */
"Enumerated", /* 10 */
NULL, /* 11 */
NULL, /* 12 */
"UTF8String", /* 12 */
NULL, /* 13 */
NULL, /* 14 */
NULL, /* 15 */

View File

@@ -102,6 +102,38 @@ copy_heim_any(const heim_any *from, heim_any *to)
return der_copy_octet_string(from, to);
}
int
encode_HEIM_ANY(unsigned char *p, size_t len,
const heim_any *data, size_t *size)
{
return encode_heim_any(p, len, data, size);
}
int
decode_HEIM_ANY(const unsigned char *p, size_t len,
heim_any *data, size_t *size)
{
return decode_heim_any(p, len, data, size);
}
void
free_HEIM_ANY(heim_any *data)
{
der_free_octet_string(data);
}
size_t
length_HEIM_ANY(const heim_any *data)
{
return data->length;
}
int
copy_HEIM_ANY(const heim_any *from, heim_any *to)
{
return der_copy_octet_string(from, to);
}
int
encode_heim_any_set(unsigned char *p, size_t len,
const heim_any_set *data, size_t *size)
@@ -139,3 +171,41 @@ heim_any_cmp(const heim_any_set *p, const heim_any_set *q)
{
return der_heim_octet_string_cmp(p, q);
}
int
encode_HEIM_ANY_SET(unsigned char *p, size_t len,
const heim_any_set *data, size_t *size)
{
return encode_heim_any_set(p, len, data, size);
}
int
decode_HEIM_ANY_SET(const unsigned char *p, size_t len,
heim_any_set *data, size_t *size)
{
return decode_heim_any_set(p, len, data, size);
}
void
free_HEIM_ANY_SET(heim_any_set *data)
{
der_free_octet_string(data);
}
size_t
length_HEIM_ANY_SET(const heim_any *data)
{
return data->length;
}
int
copy_HEIM_ANY_SET(const heim_any_set *from, heim_any_set *to)
{
return der_copy_octet_string(from, to);
}
int
HEIM_ANY_cmp(const heim_any_set *p, const heim_any_set *q)
{
return der_heim_octet_string_cmp(p, q);
}

View File

@@ -234,7 +234,9 @@ init_generate (const char *filename, const char *base)
"} heim_bit_string;\n\n");
fprintf (headerfile,
"typedef struct heim_base_data heim_any;\n"
"typedef struct heim_base_data heim_any_set;\n\n");
"typedef struct heim_base_data heim_any_set;\n"
"typedef struct heim_base_data HEIM_ANY;\n"
"typedef struct heim_base_data HEIM_ANY_SET;\n\n");
fputs("#define ASN1_MALLOC_ENCODE(T, B, BL, S, L, R) \\\n"
" do { \\\n"
" (BL) = length_##T((S)); \\\n"
@@ -643,7 +645,12 @@ define_asn1 (int level, Type *t)
{
switch (t->type) {
case TType:
fprintf (headerfile, "%s", t->symbol->name);
if (!t->symbol && t->typeref.iosclass) {
fprintf(headerfile, "%s.&%s",
t->typeref.iosclass->symbol->name,
t->typeref.field->name);
} else
fprintf(headerfile, "%s", t->symbol->name);
break;
case TInteger:
if(t->members == NULL) {
@@ -810,8 +817,215 @@ getnewbasename(char **newbasename, int typedefp, const char *basename, const cha
err(1, "malloc");
}
static void define_type(int, const char *, const char *, Type *, Type *, int, int);
/*
* Get the SET/SEQUENCE member pair and CLASS field pair defining an open type.
*
* There are three cases:
*
* - open types embedded in OCTET STRING, with the open type object class
* relation declared via a constraint
*
* - open types not embedded in OCTET STRING, which are really more like ANY
* DEFINED BY types, so, HEIM_ANY
*
* - open types in a nested structure member where the type ID field is in a
* member of the ancestor structure (this happens in PKIX's `AttributeSet',
* where the open type is essentially a SET OF HEIM_ANY).
*
* In a type like PKIX's SingleAttribute the type ID member would be the one
* named "type" and the open type member would be the one named "value", and
* the corresponding fields of the ATTRIBUTE class would be named "id" and
* "Type".
*
* NOTE: We assume a single open type member pair in any SET/SEQUENCE. In
* principle there could be more pairs and we could iterate them, or
* better yet, we could be given the name of an open type member and then
* just find its related type ID member and fields, then our caller would
* iterate the SET/SEQUENCE type's members looking for open type members
* and would call this function for each one found.
*/
void
get_open_type_defn_fields(const Type *t,
Member **typeidmember,
Member **opentypemember,
Field **typeidfield,
Field **opentypefield,
int *is_array_of)
{
Member *m;
Field *junk1, *junk2;
char *idmembername = NULL;
if (!typeidfield) typeidfield = &junk1;
if (!opentypefield) opentypefield = &junk2;
*typeidfield = *opentypefield = NULL;
*typeidmember = *opentypemember = NULL;
*is_array_of = 0;
/* Look for the open type member */
HEIM_TAILQ_FOREACH(m, t->members, members) {
Type *subtype = m->type;
Type *sOfType = NULL;
while (subtype->type == TTag ||
subtype->type == TSetOf ||
subtype->type == TSequenceOf) {
if (subtype->type == TTag && subtype->subtype) {
if (subtype->subtype->type == TOctetString ||
subtype->subtype->type == TBitString)
break;
subtype = subtype->subtype;
} else if (subtype->type == TSetOf || subtype->type == TSequenceOf) {
sOfType = subtype;
if (sOfType->symbol)
break;
if (subtype->subtype)
subtype = subtype->subtype;
} else
break;
}
/*
* If we traversed through a non-inlined SET OF or SEQUENCE OF type,
* then this cannot be an open type field.
*/
if (sOfType && sOfType->symbol)
continue;
/*
* The type of the field we're interested in has to have an information
* object constraint.
*/
if (!subtype->constraint)
continue;
if (subtype->type != TType && subtype->type != TTag)
continue;
/*
* Check if it's an ANY-like member or like an OCTET STRING CONTAINING
* member. Those are the only two possibilities.
*/
if ((subtype->type == TTag || subtype->type == TType) &&
subtype->subtype &&
subtype->constraint->ctype == CT_CONTENTS &&
subtype->constraint->u.content.type &&
subtype->constraint->u.content.type->type == TType &&
!subtype->constraint->u.content.type->subtype &&
subtype->constraint->u.content.type->constraint &&
subtype->constraint->u.content.type->constraint->ctype == CT_TABLE_CONSTRAINT) {
/* Type like OCTET STRING or BIT STRING CONTAINING open type */
*opentypemember = m;
*opentypefield = subtype->constraint->u.content.type->typeref.field;
*is_array_of = sOfType != NULL;
idmembername = subtype->constraint->u.content.type->constraint->u.content.crel.membername;
break;
} else if (subtype->symbol && strcmp(subtype->symbol->name, "HEIM_ANY") == 0) {
/* Open type, but NOT embedded in OCTET STRING or BIT STRING */
*opentypemember = m;
*opentypefield = subtype->typeref.field;
*is_array_of = sOfType != NULL;
idmembername = subtype->constraint->u.content.crel.membername;
break;
}
}
/* Look for the type ID member identified in the previous loop */
HEIM_TAILQ_FOREACH(m, t->members, members) {
if (!m->type->subtype || strcmp(m->name, idmembername))
continue;
if (m->type->constraint &&
m->type->constraint->ctype == CT_TABLE_CONSTRAINT)
*typeidfield = m->type->typeref.field;
else if (m->type->subtype->constraint &&
m->type->subtype->constraint->ctype == CT_TABLE_CONSTRAINT)
*typeidfield = m->type->subtype->typeref.field;
else
continue;
/* This is the type ID field (because there _is_ a subtype) */
*typeidmember = m;
break;
}
}
/*
* Generate CHOICE-like struct fields for open types declared via
* X.681/682/683 syntax.
*
* We could support multiple open type members in a SET/SEQUENCE, but for now
* we support only one.
*/
static void
define_type (int level, const char *name, const char *basename, Type *t, int typedefp, int preservep)
define_open_type(int level, const char *newbasename, const char *name, const char *basename, Type *pt, Type *t)
{
Member *opentypemember, *typeidmember;
Field *opentypefield, *typeidfield;
ObjectField *of;
IOSObjectSet *os = pt->actual_parameter;
IOSObject **objects;
size_t nobjs, i;
int is_array_of_open_type;
get_open_type_defn_fields(pt, &typeidmember, &opentypemember,
&typeidfield, &opentypefield,
&is_array_of_open_type);
if (!opentypemember || !typeidmember ||
!opentypefield || !typeidfield)
errx(1, "Open type specification in %s is incomplete", name);
sort_object_set(os, typeidfield, &objects, &nobjs);
fprintf(headerfile, "struct {\n");
/* Iterate objects in the object set, gen enum labels */
fprintf(headerfile, "enum { choice_%s_iosnumunknown = 0,\n",
newbasename);
for (i = 0; i < nobjs; i++) {
HEIM_TAILQ_FOREACH(of, objects[i]->objfields, objfields) {
if (strcmp(of->name, typeidfield->name))
continue;
if (!of->value || !of->value->s)
errx(1, "Unknown value in value field %s of object %s",
of->name, objects[i]->symbol->name);
fprintf(headerfile, "choice_%s_iosnum_%s,\n",
newbasename, of->value->s->gen_name);
}
}
fprintf(headerfile, "} element;\n");
if (is_array_of_open_type)
fprintf(headerfile, "unsigned int len;\n");
/* Iterate objects in the object set, gen union arms */
fprintf(headerfile, "union {\nvoid *_any;\n");
for (i = 0; i < nobjs; i++) {
HEIM_TAILQ_FOREACH(of, objects[i]->objfields, objfields) {
char *n = NULL;
if (strcmp(of->name, opentypefield->name))
continue;
if (!of->type || (!of->type->symbol && of->type->type != TTag) ||
of->type->tag.tagclass != ASN1_C_UNIV) {
warnx("Ignoring unknown or unset type field %s of object %s",
of->name, objects[i]->symbol->name);
continue;
}
if (asprintf(&n, "*%s", objects[i]->symbol->gen_name) < 0 || n == NULL)
err(1, "malloc");
define_type(level + 2, n, newbasename, NULL, of->type, FALSE, FALSE);
free(n);
}
}
if (is_array_of_open_type) {
fprintf(headerfile, "} *val;\n} _ioschoice_%s;\n", opentypemember->gen_name);
} else {
fprintf(headerfile, "} u;\n");
fprintf(headerfile, "} _ioschoice_%s;\n", opentypemember->gen_name);
}
free(objects);
}
static void
define_type(int level, const char *name, const char *basename, Type *pt, Type *t, int typedefp, int preservep)
{
const char *label_prefix = NULL;
const char *label_prefix_sep = NULL;
@@ -820,7 +1034,12 @@ define_type (int level, const char *name, const char *basename, Type *t, int typ
switch (t->type) {
case TType:
space(level);
fprintf(headerfile, "%s %s;\n", t->symbol->gen_name, name);
if (!t->symbol && t->actual_parameter)
define_open_type(level, newbasename, name, basename, t, t);
else if (!t->symbol && pt->actual_parameter)
define_open_type(level, newbasename, name, basename, pt, t);
else
fprintf(headerfile, "%s %s;\n", t->symbol->gen_name, name);
break;
case TInteger:
if (t->symbol && t->symbol->emitted_definition)
@@ -915,7 +1134,7 @@ define_type (int level, const char *name, const char *basename, Type *t, int typ
while (pos < m->val) {
if (asprintf (&n, "_unused%d:1", pos) < 0 || n == NULL)
err(1, "malloc");
define_type (level + 1, n, newbasename, &i, FALSE, FALSE);
define_type(level + 1, n, newbasename, NULL, &i, FALSE, FALSE);
free(n);
pos++;
}
@@ -923,7 +1142,7 @@ define_type (int level, const char *name, const char *basename, Type *t, int typ
n = NULL;
if (asprintf (&n, "%s:1", m->gen_name) < 0 || n == NULL)
errx(1, "malloc");
define_type (level + 1, n, newbasename, &i, FALSE, FALSE);
define_type(level + 1, n, newbasename, NULL, &i, FALSE, FALSE);
free (n);
n = NULL;
pos++;
@@ -938,7 +1157,7 @@ define_type (int level, const char *name, const char *basename, Type *t, int typ
char *n = NULL;
if (asprintf (&n, "_unused%d:1", pos) < 0 || n == NULL)
errx(1, "malloc");
define_type (level + 1, n, newbasename, &i, FALSE, FALSE);
define_type(level + 1, n, newbasename, NULL, &i, FALSE, FALSE);
free(n);
pos++;
}
@@ -989,13 +1208,15 @@ define_type (int level, const char *name, const char *basename, Type *t, int typ
} else if (m->optional) {
char *n = NULL;
if (asprintf (&n, "*%s", m->gen_name) < 0 || n == NULL)
if (asprintf(&n, "*%s", m->gen_name) < 0 || n == NULL)
errx(1, "malloc");
define_type (level + 1, n, newbasename, m->type, FALSE, FALSE);
define_type(level + 1, n, newbasename, t, m->type, FALSE, FALSE);
free (n);
} else
define_type (level + 1, m->gen_name, newbasename, m->type, FALSE, FALSE);
define_type(level + 1, m->gen_name, newbasename, t, m->type, FALSE, FALSE);
}
if (t->actual_parameter && t->actual_parameter->objects)
define_open_type(level, newbasename, name, basename, t, t);
space(level);
fprintf (headerfile, "} %s;\n", name);
break;
@@ -1013,8 +1234,8 @@ define_type (int level, const char *name, const char *basename, Type *t, int typ
space(level);
fprintf (headerfile, "struct %s {\n", newbasename);
define_type (level + 1, "len", newbasename, &i, FALSE, FALSE);
define_type (level + 1, "*val", newbasename, t->subtype, FALSE, FALSE);
define_type(level + 1, "len", newbasename, t, &i, FALSE, FALSE);
define_type(level + 1, "*val", newbasename, t, t->subtype, FALSE, FALSE);
space(level);
fprintf (headerfile, "} %s;\n", name);
break;
@@ -1032,7 +1253,7 @@ define_type (int level, const char *name, const char *basename, Type *t, int typ
fprintf (headerfile, "heim_general_string %s;\n", name);
break;
case TTag:
define_type (level, name, basename, t->subtype, typedefp, preservep);
define_type(level, name, basename, t, t->subtype, typedefp, preservep);
break;
case TChoice: {
int first = 1;
@@ -1077,10 +1298,10 @@ define_type (int level, const char *name, const char *basename, Type *t, int typ
if (asprintf (&n, "*%s", m->gen_name) < 0 || n == NULL)
errx(1, "malloc");
define_type (level + 2, n, newbasename, m->type, FALSE, FALSE);
define_type(level + 2, n, newbasename, t, m->type, FALSE, FALSE);
free (n);
} else
define_type (level + 2, m->gen_name, newbasename, m->type, FALSE, FALSE);
define_type(level + 2, m->gen_name, newbasename, t, m->type, FALSE, FALSE);
}
space(level + 1);
fprintf (headerfile, "} u;\n");
@@ -1140,7 +1361,7 @@ declare_type(const Symbol *s, Type *t, int typedefp)
switch (t->type) {
case TType:
define_type(0, s->gen_name, s->gen_name, s->type, TRUE, TRUE);
define_type(0, s->gen_name, s->gen_name, NULL, s->type, TRUE, TRUE);
if (template_flag)
generate_template_type_forward(s->gen_name);
emitted_declaration(s);
@@ -1162,7 +1383,7 @@ declare_type(const Symbol *s, Type *t, int typedefp)
case TVisibleString:
case TOID :
case TNull:
define_type(0, s->gen_name, s->gen_name, s->type, TRUE, TRUE);
define_type(0, s->gen_name, s->gen_name, NULL, s->type, TRUE, TRUE);
if (template_flag)
generate_template_type_forward(s->gen_name);
emitted_declaration(s);
@@ -1295,10 +1516,12 @@ generate_subtypes_header(const Symbol *s)
switch (t->type) {
default: return;
case TType:
if (t->symbol && (s = getsym(t->symbol->name)))
generate_type_header(s);
case TType: {
Symbol *s2;
if (t->symbol && (s2 = getsym(t->symbol->name)) != s)
generate_type_header(s2);
return;
}
case TSet:
case TSequence:
case TChoice:
@@ -1342,10 +1565,14 @@ generate_type_header (const Symbol *s)
* needed in stripped objects.
*/
if (!s->emitted_tag_enums) {
while (t->type == TType && s->type->symbol && s->type->symbol->type)
t = s->type->symbol->type;
while (t->type == TType && s->type->symbol && s->type->symbol->type) {
if (t->subtype)
t = t->subtype;
else
t = s->type->symbol->type;
}
if (t->type == TType && t->symbol && strcmp(t->symbol->name, "heim_any")) {
if (t->type == TType && t->symbol && strcmp(t->symbol->name, "HEIM_ANY")) {
/*
* This type is ultimately an alias of an imported type, so we don't
* know its outermost tag here.
@@ -1375,13 +1602,10 @@ generate_type_header (const Symbol *s)
return;
fprintf(headerfile, "typedef ");
define_type(0, s->gen_name, s->gen_name, s->type, TRUE,
define_type(0, s->gen_name, s->gen_name, NULL, s->type, TRUE,
preserve_type(s->name) ? TRUE : FALSE);
fprintf(headerfile, "\n");
if (template_flag)
generate_template_type_forward(s->gen_name);
emitted_definition(s);
}
@@ -1390,6 +1614,8 @@ generate_type_header_forwards(const Symbol *s)
{
declare_type(s, s->type, TRUE);
fprintf(headerfile, "\n");
if (template_flag)
generate_template_type_forward(s->gen_name);
}
void

View File

@@ -531,7 +531,7 @@ decode_type(const char *name, const Type *t, int optional, struct value *defval,
(t->subtype->type == TSequence ||
t->subtype->type == TSet))
replace_tag = 1;
else if (t->subtype->symbol && strcmp(t->subtype->symbol->name, "heim_any"))
else if (t->subtype->symbol && strcmp(t->subtype->symbol->name, "HEIM_ANY"))
replace_tag = 1;
} else if (t->tag.tagenv == TE_IMPLICIT && prim && t->subtype->symbol)
replace_tag = 1;

View File

@@ -103,17 +103,9 @@ generate_units (const Type *t, const char *gen_name)
{
Member *m;
if (template_flag) {
fprintf (headerfile,
"extern const struct units *asn1_%s_table_units;\n",
gen_name);
fprintf (headerfile, "#define asn1_%s_units() (asn1_%s_table_units)\n",
gen_name, gen_name);
} else {
fprintf (headerfile,
"const struct units * asn1_%s_units(void);\n",
gen_name);
}
fprintf (headerfile,
"const struct units * asn1_%s_units(void);\n",
gen_name);
fprintf (get_code_file(),
"static struct units %s_units[] = {\n",
@@ -130,16 +122,11 @@ generate_units (const Type *t, const char *gen_name)
"\t{NULL,\t0}\n"
"};\n\n");
if (template_flag)
fprintf (get_code_file(),
"const struct units * asn1_%s_table_units = %s_units;\n",
gen_name, gen_name);
else
fprintf (get_code_file(),
"const struct units * asn1_%s_units(void){\n"
"return %s_units;\n"
"}\n\n",
gen_name, gen_name);
fprintf (get_code_file(),
"const struct units * asn1_%s_units(void){\n"
"return %s_units;\n"
"}\n\n",
gen_name, gen_name);
}

View File

@@ -128,6 +128,7 @@ const char *valuename(Der_class, int);
void gen_compare_defval(const char *, struct value *);
void gen_assign_defval(const char *, struct value *);
int objid_cmp(struct objid *, struct objid *);
void init_generate (const char *, const char *);
const char *get_filename (void);
@@ -144,9 +145,15 @@ int seq_type(const char *);
void generate_header_of_codefile(const char *);
void close_codefile(void);
void get_open_type_defn_fields(const Type *, Member **, Member **, Field **,
Field **, int *);
void sort_object_set(IOSObjectSet *, Field *, IOSObject ***, size_t *);
int is_template_compat (const Symbol *);
void generate_template(const Symbol *);
void generate_template_type_forward(const char *);
void generate_template_objectset_forwards(const Symbol *);
void gen_template_import(const Symbol *);

View File

@@ -295,6 +295,8 @@ 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 void add_line_pointer_reference(struct templatehead *, const char *, const char *, const char *, ...)
__attribute__ ((__format__ (__printf__, 4, 5)));
static struct tlisthead tlistmaster = HEIM_TAILQ_HEAD_INITIALIZER(tlistmaster);
@@ -426,7 +428,7 @@ tlist_find_dup(const struct tlist *tl)
/*
*
* Add an entry to a template.
*/
static struct template *
@@ -442,6 +444,10 @@ add_line(struct templatehead *t, const char *fmt, ...)
return q;
}
/*
* Add an entry to a template, with the pointer field bein a symbol name of a
* template (i.e., an array, which decays to a pointer as usual in C).
*/
static void
add_line_pointer(struct templatehead *t,
const char *ptr,
@@ -464,6 +470,28 @@ add_line_pointer(struct templatehead *t,
q->ptr = strdup(ptr);
}
static void
add_line_pointer_reference(struct templatehead *t,
const char *ptr,
const char *offset,
const char *ttfmt,
...)
{
struct template *q;
va_list ap;
char *tt = NULL;
va_start(ap, ttfmt);
if (vasprintf(&tt, ttfmt, ap) < 0 || tt == NULL)
errx(1, "malloc");
va_end(ap);
q = add_line(t, "{ %s, %s, (const void *)&asn1_%s }", tt, offset, ptr);
q->tt = tt;
q->offset = strdup(offset);
q->ptr = strdup(ptr);
}
static int
use_extern(const Symbol *s)
{
@@ -598,6 +626,229 @@ defval(struct templatehead *temp, Member *m)
}
}
int
objid_cmp(struct objid *oida, struct objid *oidb)
{
struct objid *p;
size_t ai, bi, alen, blen;
int avals[20];
int bvals[20];
int c;
/*
* Our OID values are backwards here. Comparing them is hard.
*/
for (p = oida, alen = 0;
p && alen < sizeof(avals)/sizeof(avals[0]);
p = p->next)
avals[alen++] = p->value;
for (p = oidb, blen = 0;
p && blen < sizeof(bvals)/sizeof(bvals[0]);
p = p->next)
bvals[blen++] = p->value;
if (alen >= sizeof(avals)/sizeof(avals[0]) ||
blen >= sizeof(bvals)/sizeof(bvals[0]))
err(1, "OIDs with more components than %llu not supported",
(unsigned long long)sizeof(avals)/sizeof(avals[0]));
for (ai = 0, bi = 0; ai < alen && bi < blen;)
if ((c = avals[(alen-1)-(ai++)] - bvals[(blen-1)-(bi++)]))
return c;
if (ai == alen && bi == blen)
return 0;
if (ai == alen)
return 1;
return -1;
}
static int
object_cmp(const void *va, const void *vb)
{
const IOSObject *oa = *(const IOSObject * const *)va;
const IOSObject *ob = *(const IOSObject * const *)vb;
switch (oa->typeidf->value->type) {
case booleanvalue:
return oa->typeidf->value->u.booleanvalue -
ob->typeidf->value->u.booleanvalue;
case nullvalue:
return 0;
case integervalue:
return oa->typeidf->value->u.integervalue -
ob->typeidf->value->u.integervalue;
case stringvalue:
return strcmp(oa->typeidf->value->u.stringvalue,
ob->typeidf->value->u.stringvalue);
case objectidentifiervalue: {
return objid_cmp(oa->typeidf->value->u.objectidentifiervalue,
ob->typeidf->value->u.objectidentifiervalue);
}
default:
abort();
return -1;
}
}
void
sort_object_set(IOSObjectSet *os, /* Object set to sort fields of */
Field *typeidfield, /* Field to sort by */
IOSObject ***objectsp, /* Output: array of objects */
size_t *nobjsp) /* Output: count of objects */
{
IOSObject **objects;
IOSObject *o;
size_t i, nobjs = 0;
/* FIXME: This would be a good place to check field UNIQUE constraints */
HEIM_TAILQ_FOREACH(o, os->objects, objects) {
ObjectField *typeidobjf = NULL;
ObjectField *of;
HEIM_TAILQ_FOREACH(of, o->objfields, objfields) {
if (strcmp(of->name, typeidfield->name) == 0)
typeidobjf = of;
}
if (!typeidobjf) {
warnx("Ignoring incomplete object specification of %s "
"(missing type ID field)",
o->symbol ? o->symbol->name : "<unknown>");
continue;
}
o->typeidf = typeidobjf;
nobjs++;
}
*nobjsp = nobjs;
if ((objects = calloc(nobjs, sizeof(*objects))) == NULL)
err(1, "Out of memory");
*objectsp = objects;
i = 0;
HEIM_TAILQ_FOREACH(o, os->objects, objects) {
ObjectField *typeidobjf = NULL;
ObjectField *of;
HEIM_TAILQ_FOREACH(of, o->objfields, objfields) {
if (strcmp(of->name, typeidfield->name) == 0)
typeidobjf = of;
}
if (typeidobjf)
objects[i++] = o;
}
qsort(objects, nobjs, sizeof(*objects), object_cmp);
}
static void
template_object_set(IOSObjectSet *os, Field *typeidfield, Field *opentypefield)
{
IOSObject **objects;
IOSObject *o;
struct tlist *tl;
size_t nobjs, i;
if (os->symbol->emitted_template)
return;
sort_object_set(os, typeidfield, &objects, &nobjs);
tl = tlist_new(os->symbol->name);
for (i = 0; i < nobjs; i++) {
ObjectField *typeidobjf = NULL, *opentypeobjf = NULL;
ObjectField *of;
char *s = NULL;
o = objects[i];
HEIM_TAILQ_FOREACH(of, o->objfields, objfields) {
if (strcmp(of->name, typeidfield->name) == 0)
typeidobjf = of;
else if (strcmp(of->name, opentypefield->name) == 0)
opentypeobjf = of;
}
if (!typeidobjf)
continue; /* We've warned about this one already when sorting */
if (!opentypeobjf) {
warnx("Ignoring incomplete object specification of %s "
"(missing open type field)",
o->symbol ? o->symbol->name : "<unknown>");
continue;
}
/*
* Some of this logic could stand to move into sanity checks of object
* definitions in asn1parse.y.
*/
switch (typeidobjf->value->type) {
case integervalue:
add_line(&tl->template,
"{ A1_OP_OPENTYPE_ID | A1_OTI_IS_INTEGER, 0, (void *)%lld }",
(long long)typeidobjf->value->u.integervalue);
break;
case objectidentifiervalue:
if (asprintf(&s, "oid_%s",
typeidobjf->value->s->gen_name) == -1 || !s)
err(1, "Out of memory");
add_line_pointer_reference(&tl->template, s, "0", "A1_OP_OPENTYPE_ID");
free(s);
s = NULL;
break;
default:
errx(1, "Only integer and OID types supported "
"for open type type-ID fields");
}
if (asprintf(&s, "sizeof(%s)",
opentypeobjf->type->symbol->gen_name) == -1 || !s)
err(1, "Out of memory");
add_line_pointer_reference(&tl->template,
opentypeobjf->type->symbol->gen_name, s,
"A1_OP_OPENTYPE");
free(s);
}
free(objects);
tlist_header(tl, "{ 0, 0, ((void *)%lu) }", nobjs);
tlist_print(tl);
tlist_add(tl);
os->symbol->emitted_template = 1;
}
static void
template_open_type(struct templatehead *temp,
const char *basetype,
const Type *t,
size_t typeididx,
size_t opentypeidx,
Field *typeidfield,
Field *opentypefield,
Member *m,
int is_array_of_open_type)
{
char *s = NULL;
if (typeididx >= 1<<10 || opentypeidx >= 1<<10)
errx(1, "SET/SEQUENCE with too many members (%s)", basetype);
if (asprintf(&s, "offsetof(%s, _ioschoice_%s)",
basetype, m->gen_name) == -1 || !s)
err(1, "Out of memory");
template_object_set(t->actual_parameter, typeidfield, opentypefield);
add_line_pointer(temp, t->actual_parameter->symbol->gen_name, s,
/*
* We always sort object sets for now as we can't import
* values yet, so they must all be known.
*/
"A1_OP_OPENTYPE_OBJSET | A1_OS_IS_SORTED |%s | (%llu << 10) | %llu",
is_array_of_open_type ? "A1_OS_OT_IS_ARRAY" : "0",
(unsigned long long)opentypeidx,
(unsigned long long)typeididx);
free(s);
}
static void
template_members(struct templatehead *temp,
const char *basetype,
@@ -742,7 +993,18 @@ template_members(struct templatehead *temp,
break;
}
case TSet: {
Member *opentypemember = NULL;
Member *typeidmember = NULL;
Field *opentypefield = NULL;
Field *typeidfield = NULL;
Member *m;
size_t i = 0, typeididx = 0, opentypeidx = 0;
int is_array_of_open_type = 0;
if (isstruct && t->actual_parameter)
get_open_type_defn_fields(t, &typeidmember, &opentypemember,
&typeidfield, &opentypefield,
&is_array_of_open_type);
fprintf(get_code_file(), "/* tset: members isstruct: %d */\n", isstruct);
@@ -752,6 +1014,9 @@ template_members(struct templatehead *temp,
if (m->ellipsis)
continue;
if (typeidmember == m) typeididx = i;
if (opentypemember == m) opentypeidx = i;
if (name) {
if (asprintf(&newbasename, "%s_%s", basetype, name) < 0)
errx(1, "malloc");
@@ -766,12 +1031,28 @@ template_members(struct templatehead *temp,
template_members(temp, newbasename, m->gen_name, m->type, m->optional, m->defval ? 1 : 0, 0, isstruct, 1);
free(newbasename);
i++;
}
if (isstruct && t->actual_parameter)
template_open_type(temp, basetype, t, typeididx, opentypeidx,
typeidfield, opentypefield, opentypemember,
is_array_of_open_type);
break;
}
case TSequence: {
Member *opentypemember = NULL;
Member *typeidmember = NULL;
Field *opentypefield = NULL;
Field *typeidfield = NULL;
Member *m;
size_t i = 0, typeididx = 0, opentypeidx = 0;
int is_array_of_open_type = 0;
if (isstruct && t->actual_parameter)
get_open_type_defn_fields(t, &typeidmember, &opentypemember,
&typeidfield, &opentypefield,
&is_array_of_open_type);
fprintf(get_code_file(), "/* tsequence: members isstruct: %d */\n", isstruct);
@@ -781,6 +1062,9 @@ template_members(struct templatehead *temp,
if (m->ellipsis)
continue;
if (typeidmember == m) typeididx = i;
if (opentypemember == m) opentypeidx = i;
if (name) {
if (asprintf(&newbasename, "%s_%s", basetype, name) < 0)
errx(1, "malloc");
@@ -795,8 +1079,13 @@ template_members(struct templatehead *temp,
template_members(temp, newbasename, m->gen_name, m->type, m->optional, m->defval ? 1 : 0, 0, isstruct, 1);
free(newbasename);
i++;
}
if (isstruct && t->actual_parameter)
template_open_type(temp, basetype, t, typeididx, opentypeidx,
typeidfield, opentypefield, opentypemember,
is_array_of_open_type);
break;
}
case TTag: {
@@ -1010,6 +1299,15 @@ generate_template_type_forward(const char *name)
fprintf(get_code_file(), "extern const struct asn1_template asn1_%s[];\n", name);
}
void
generate_template_objectset_forwards(const Symbol *s)
{
if (!template_flag)
return;
fprintf(get_code_file(), "extern const struct asn1_template asn1_%s[];\n",
s->gen_name);
}
static void
generate_template_type(const char *varname,
const char **dupname,

View File

@@ -49,4 +49,19 @@ size_t length_heim_any_set(const heim_any_set *);
int copy_heim_any_set(const heim_any_set *, heim_any_set *);
int heim_any_cmp(const heim_any_set *, const heim_any_set *);
int encode_HEIM_ANY(unsigned char *, size_t, const heim_any *, size_t *);
int decode_HEIM_ANY(const unsigned char *, size_t, heim_any *, size_t *);
void free_HEIM_ANY(heim_any *);
size_t length_HEIM_ANY(const heim_any *);
int copy_HEIM_ANY(const heim_any *, heim_any *);
int encode_HEIM_ANY_SET(unsigned char *, size_t,
const heim_any_set *, size_t *);
int decode_HEIM_ANY_SET(const unsigned char *, size_t,
heim_any_set *,size_t *);
void free_HEIM_ANY_SET(heim_any_set *);
size_t length_HEIM_ANY_SET(const heim_any_set *);
int copy_HEIM_ANY_SET(const heim_any_set *, heim_any_set *);
int heim_any_cmp(const heim_any_set *, const heim_any_set *);
#endif /* __HEIM_ANY_H__ */

View File

@@ -286,8 +286,8 @@ ENCTYPE ::= INTEGER {
-- this is sugar to make something ASN1 does not have: unsigned
krb5uint32 ::= INTEGER (0..4294967295)
krb5int32 ::= INTEGER (-2147483648..2147483647)
Krb5UInt32 ::= INTEGER (0..4294967295)
Krb5Int32 ::= INTEGER (-2147483648..2147483647)
KerberosString ::= GeneralString
@@ -306,14 +306,14 @@ Principal ::= SEQUENCE {
Principals ::= SEQUENCE OF Principal
HostAddress ::= SEQUENCE {
addr-type[0] krb5int32,
addr-type[0] Krb5Int32,
address[1] OCTET STRING
}
-- This is from RFC1510.
--
-- HostAddresses ::= SEQUENCE OF SEQUENCE {
-- addr-type[0] krb5int32,
-- addr-type[0] Krb5Int32,
-- address[1] OCTET STRING
-- }
@@ -324,7 +324,7 @@ HostAddresses ::= SEQUENCE OF HostAddress
KerberosTime ::= GeneralizedTime -- Specifying UTC time zone (Z)
AuthorizationDataElement ::= SEQUENCE {
ad-type[0] krb5int32,
ad-type[0] Krb5Int32,
ad-data[1] OCTET STRING
}
@@ -393,23 +393,23 @@ LastReq ::= SEQUENCE OF SEQUENCE {
EncryptedData ::= SEQUENCE {
etype[0] ENCTYPE, -- EncryptionType
kvno[1] krb5int32 OPTIONAL,
kvno[1] Krb5Int32 OPTIONAL,
cipher[2] OCTET STRING -- ciphertext
}
EncryptionKey ::= SEQUENCE {
keytype[0] krb5int32,
keytype[0] Krb5Int32,
keyvalue[1] OCTET STRING
}
-- encoded Transited field
TransitedEncoding ::= SEQUENCE {
tr-type[0] krb5int32, -- must be registered
tr-type[0] Krb5Int32, -- must be registered
contents[1] OCTET STRING
}
Ticket ::= [APPLICATION 1] SEQUENCE {
tkt-vno[0] krb5int32,
tkt-vno[0] Krb5Int32,
realm[1] Realm,
sname[2] PrincipalName,
enc-part[3] EncryptedData
@@ -435,14 +435,14 @@ Checksum ::= SEQUENCE {
}
Authenticator ::= [APPLICATION 2] SEQUENCE {
authenticator-vno[0] krb5int32,
authenticator-vno[0] Krb5Int32,
crealm[1] Realm,
cname[2] PrincipalName,
cksum[3] Checksum OPTIONAL,
cusec[4] krb5int32,
cusec[4] Krb5Int32,
ctime[5] KerberosTime,
subkey[6] EncryptionKey OPTIONAL,
seq-number[7] krb5uint32 OPTIONAL,
seq-number[7] Krb5UInt32 OPTIONAL,
authorization-data[8] AuthorizationData OPTIONAL
}
@@ -455,7 +455,7 @@ PA-DATA ::= SEQUENCE {
ETYPE-INFO-ENTRY ::= SEQUENCE {
etype[0] ENCTYPE,
salt[1] OCTET STRING OPTIONAL,
salttype[2] krb5int32 OPTIONAL
salttype[2] Krb5Int32 OPTIONAL
}
ETYPE-INFO ::= SEQUENCE OF ETYPE-INFO-ENTRY
@@ -471,7 +471,7 @@ ETYPE-INFO2 ::= SEQUENCE SIZE (1..MAX) OF ETYPE-INFO2-ENTRY
METHOD-DATA ::= SEQUENCE OF PA-DATA
TypedData ::= SEQUENCE {
data-type[0] krb5int32,
data-type[0] Krb5Int32,
data-value[1] OCTET STRING OPTIONAL
}
@@ -486,7 +486,7 @@ KDC-REQ-BODY ::= SEQUENCE {
from[4] KerberosTime OPTIONAL,
till[5] KerberosTime OPTIONAL,
rtime[6] KerberosTime OPTIONAL,
nonce[7] krb5int32,
nonce[7] Krb5Int32,
etype[8] SEQUENCE OF ENCTYPE, -- EncryptionType,
-- in preference order
addresses[9] HostAddresses OPTIONAL,
@@ -496,7 +496,7 @@ KDC-REQ-BODY ::= SEQUENCE {
}
KDC-REQ ::= SEQUENCE {
pvno[1] krb5int32,
pvno[1] Krb5Int32,
msg-type[2] MESSAGE-TYPE,
padata[3] METHOD-DATA OPTIONAL,
req-body[4] KDC-REQ-BODY
@@ -510,7 +510,7 @@ TGS-REQ ::= [APPLICATION 12] KDC-REQ
PA-ENC-TS-ENC ::= SEQUENCE {
patimestamp[0] KerberosTime, -- client's time
pausec[1] krb5int32 OPTIONAL
pausec[1] Krb5Int32 OPTIONAL
}
-- draft-brezak-win2k-krb-authz-01
@@ -523,7 +523,7 @@ PA-PAC-REQUEST ::= SEQUENCE {
PROV-SRV-LOCATION ::= GeneralString
KDC-REP ::= SEQUENCE {
pvno[0] krb5int32,
pvno[0] Krb5Int32,
msg-type[1] MESSAGE-TYPE,
padata[2] METHOD-DATA OPTIONAL,
crealm[3] Realm,
@@ -538,7 +538,7 @@ TGS-REP ::= [APPLICATION 13] KDC-REP
EncKDCRepPart ::= SEQUENCE {
key[0] EncryptionKey,
last-req[1] LastReq,
nonce[2] krb5int32,
nonce[2] Krb5Int32,
key-expiration[3] KerberosTime OPTIONAL,
flags[4] TicketFlags,
authtime[5] KerberosTime,
@@ -555,7 +555,7 @@ EncASRepPart ::= [APPLICATION 25] EncKDCRepPart
EncTGSRepPart ::= [APPLICATION 26] EncKDCRepPart
AP-REQ ::= [APPLICATION 14] SEQUENCE {
pvno[0] krb5int32,
pvno[0] Krb5Int32,
msg-type[1] MESSAGE-TYPE,
ap-options[2] APOptions,
ticket[3] Ticket,
@@ -563,50 +563,50 @@ AP-REQ ::= [APPLICATION 14] SEQUENCE {
}
AP-REP ::= [APPLICATION 15] SEQUENCE {
pvno[0] krb5int32,
pvno[0] Krb5Int32,
msg-type[1] MESSAGE-TYPE,
enc-part[2] EncryptedData
}
EncAPRepPart ::= [APPLICATION 27] SEQUENCE {
ctime[0] KerberosTime,
cusec[1] krb5int32,
cusec[1] Krb5Int32,
subkey[2] EncryptionKey OPTIONAL,
seq-number[3] krb5uint32 OPTIONAL
seq-number[3] Krb5UInt32 OPTIONAL
}
KRB-SAFE-BODY ::= SEQUENCE {
user-data[0] OCTET STRING,
timestamp[1] KerberosTime OPTIONAL,
usec[2] krb5int32 OPTIONAL,
seq-number[3] krb5uint32 OPTIONAL,
usec[2] Krb5Int32 OPTIONAL,
seq-number[3] Krb5UInt32 OPTIONAL,
s-address[4] HostAddress OPTIONAL,
r-address[5] HostAddress OPTIONAL
}
KRB-SAFE ::= [APPLICATION 20] SEQUENCE {
pvno[0] krb5int32,
pvno[0] Krb5Int32,
msg-type[1] MESSAGE-TYPE,
safe-body[2] KRB-SAFE-BODY,
cksum[3] Checksum
}
KRB-PRIV ::= [APPLICATION 21] SEQUENCE {
pvno[0] krb5int32,
pvno[0] Krb5Int32,
msg-type[1] MESSAGE-TYPE,
enc-part[3] EncryptedData
}
EncKrbPrivPart ::= [APPLICATION 28] SEQUENCE {
user-data[0] OCTET STRING,
timestamp[1] KerberosTime OPTIONAL,
usec[2] krb5int32 OPTIONAL,
seq-number[3] krb5uint32 OPTIONAL,
usec[2] Krb5Int32 OPTIONAL,
seq-number[3] Krb5UInt32 OPTIONAL,
s-address[4] HostAddress OPTIONAL, -- sender's addr
r-address[5] HostAddress OPTIONAL -- recip's addr
}
KRB-CRED ::= [APPLICATION 22] SEQUENCE {
pvno[0] krb5int32,
pvno[0] Krb5Int32,
msg-type[1] MESSAGE-TYPE, -- KRB_CRED
tickets[2] SEQUENCE OF Ticket,
enc-part[3] EncryptedData
@@ -628,21 +628,21 @@ KrbCredInfo ::= SEQUENCE {
EncKrbCredPart ::= [APPLICATION 29] SEQUENCE {
ticket-info[0] SEQUENCE OF KrbCredInfo,
nonce[1] krb5int32 OPTIONAL,
nonce[1] Krb5Int32 OPTIONAL,
timestamp[2] KerberosTime OPTIONAL,
usec[3] krb5int32 OPTIONAL,
usec[3] Krb5Int32 OPTIONAL,
s-address[4] HostAddress OPTIONAL,
r-address[5] HostAddress OPTIONAL
}
KRB-ERROR ::= [APPLICATION 30] SEQUENCE {
pvno[0] krb5int32,
pvno[0] Krb5Int32,
msg-type[1] MESSAGE-TYPE,
ctime[2] KerberosTime OPTIONAL,
cusec[3] krb5int32 OPTIONAL,
cusec[3] Krb5Int32 OPTIONAL,
stime[4] KerberosTime,
susec[5] krb5int32,
error-code[6] krb5int32,
susec[5] Krb5Int32,
error-code[6] Krb5Int32,
crealm[7] Realm OPTIONAL,
cname[8] PrincipalName OPTIONAL,
realm[9] Realm, -- Correct realm
@@ -661,11 +661,11 @@ EtypeList ::= SEQUENCE OF ENCTYPE
-- the client's proposed enctype list in
-- decreasing preference order, favorite choice first
krb5-pvno krb5int32 ::= 5 -- current Kerberos protocol version number
krb5-pvno Krb5Int32 ::= 5 -- current Kerberos protocol version number
-- transited encodings
DOMAIN-X500-COMPRESS krb5int32 ::= 1
domain-X500-Compress Krb5Int32 ::= 1
-- authorization data primitives
@@ -679,7 +679,7 @@ AD-KDCIssued ::= SEQUENCE {
}
AD-AND-OR ::= SEQUENCE {
condition-count[0] INTEGER,
condition-count[0] Krb5Int32,
elements[1] AuthorizationData
}
@@ -705,7 +705,7 @@ SAMFlags ::= BIT STRING {
}
PA-SAM-CHALLENGE-2-BODY ::= SEQUENCE {
sam-type[0] krb5int32,
sam-type[0] Krb5Int32,
sam-flags[1] SAMFlags,
sam-type-name[2] GeneralString OPTIONAL,
sam-track-id[3] GeneralString OPTIONAL,
@@ -713,8 +713,8 @@ PA-SAM-CHALLENGE-2-BODY ::= SEQUENCE {
sam-challenge[5] GeneralString OPTIONAL,
sam-response-prompt[6] GeneralString OPTIONAL,
sam-pk-for-sad[7] EncryptionKey OPTIONAL,
sam-nonce[8] krb5int32,
sam-etype[9] krb5int32,
sam-nonce[8] Krb5Int32,
sam-etype[9] Krb5Int32,
...
}
@@ -725,16 +725,16 @@ PA-SAM-CHALLENGE-2 ::= SEQUENCE {
}
PA-SAM-RESPONSE-2 ::= SEQUENCE {
sam-type[0] krb5int32,
sam-type[0] Krb5Int32,
sam-flags[1] SAMFlags,
sam-track-id[2] GeneralString OPTIONAL,
sam-enc-nonce-or-sad[3] EncryptedData, -- PA-ENC-SAM-RESPONSE-ENC
sam-nonce[4] krb5int32,
sam-nonce[4] Krb5Int32,
...
}
PA-ENC-SAM-RESPONSE-ENC ::= SEQUENCE {
sam-nonce[0] krb5int32,
sam-nonce[0] Krb5Int32,
sam-sad[1] GeneralString OPTIONAL,
...
}
@@ -799,7 +799,7 @@ KrbFastReq ::= SEQUENCE {
}
KrbFastArmor ::= SEQUENCE {
armor-type [0] krb5int32,
armor-type [0] Krb5Int32,
armor-value [1] OCTET STRING,
...
}
@@ -817,7 +817,7 @@ PA-FX-FAST-REQUEST ::= CHOICE {
KrbFastFinished ::= SEQUENCE {
timestamp [0] KerberosTime,
usec [1] krb5int32,
usec [1] Krb5Int32,
crealm [2] Realm,
cname [3] PrincipalName,
ticket-checksum [4] Checksum,
@@ -828,7 +828,7 @@ KrbFastResponse ::= SEQUENCE {
padata [0] METHOD-DATA,
strengthen-key [1] EncryptionKey OPTIONAL,
finished [2] KrbFastFinished OPTIONAL,
nonce [3] krb5uint32,
nonce [3] Krb5UInt32,
...
}
@@ -891,7 +891,7 @@ KERB-CRED ::= SEQUENCE {
KERB-TGS-REQ-IN ::= SEQUENCE {
cache [0] OCTET STRING SIZE (16),
addrs [1] HostAddresses,
flags [2] krb5uint32,
flags [2] Krb5UInt32,
imp [3] Principal OPTIONAL,
ticket [4] OCTET STRING OPTIONAL,
in_cred [5] KERB-CRED,

View File

@@ -150,6 +150,10 @@ WITH { return kw_WITH; }
[-,;{}()|] { return *yytext; }
"[" { return *yytext; }
"]" { return *yytext; }
"&" { return *yytext; }
"." { return *yytext; }
":" { return *yytext; }
"@" { return *yytext; }
::= { return EEQUAL; }
-- {
int c, start_lineno = lineno;
@@ -250,7 +254,6 @@ WITH { return kw_WITH; }
if(c == EOF)
unterminated("string", start_lineno);
*p++ = '\0';
fprintf(stderr, "string -- %s\n", buf);
yylval.name = estrdup(buf);
return STRING;
}
@@ -263,9 +266,17 @@ WITH { return kw_WITH; }
else
return NUMBER;
}
[A-Za-z][-A-Za-z0-9_]* {
[_][-A-Z0-9]* {
yylval.name = estrdup ((const char *)yytext);
return IDENTIFIER;
return CLASS_IDENTIFIER;
}
[A-Z][-A-Za-z0-9_]* {
yylval.name = estrdup ((const char *)yytext);
return TYPE_IDENTIFIER;
}
[a-z][-A-Za-z0-9_]* {
yylval.name = estrdup ((const char *)yytext);
return VALUE_IDENTIFIER;
}
[ \t] ;
\n { ++lineno; }

View File

@@ -4,6 +4,18 @@ EXPORTS
_asn1_length
_asn1_free_top
_asn1_copy_top
_asn1_bmember_isset_bit
_asn1_bmember_put_bit
_asn1_copy
_asn1_copy_top
_asn1_decode
_asn1_decode_top
_asn1_encode
_asn1_free
_asn1_free_top
_asn1_length
_asn1_print_top
_asn1_sizeofType
add_AttributeValues
add_AuthorizationData
add_CertificatePolicies
@@ -43,6 +55,7 @@ EXPORTS
asn1_oid_id_at_countryName DATA
asn1_oid_id_at_description DATA
asn1_oid_id_at_dnQualifier DATA
asn1_oid_id_at_emailAddress DATA
asn1_oid_id_at_generationQualifier DATA
asn1_oid_id_at_givenName DATA
asn1_oid_id_at_initials DATA
@@ -92,9 +105,7 @@ EXPORTS
asn1_oid_id_nist_aes_algs DATA
asn1_oid_id_nistAlgorithm DATA
asn1_oid_id_nist_sha_algs DATA
asn1_oid_id_on DATA
asn1_oid_id_on_hardwareModuleName DATA
asn1_oid_id_on_permanentIdentifier DATA
asn1_oid_id_pbeWithSHAAnd128BitRC2_CBC DATA
asn1_oid_id_pbeWithSHAAnd128BitRC4 DATA
asn1_oid_id_pbeWithSHAAnd2_KeyTripleDES_CBC DATA
@@ -191,6 +202,10 @@ EXPORTS
asn1_oid_id_pkix_ocsp_nonce DATA
asn1_oid_id_pkix_on DATA
asn1_oid_id_pkix_on_dnsSRV DATA
asn1_oid_id_pkix_on_hardwareModuleName DATA
asn1_oid_id_pkix_on_permanentIdentifier DATA
asn1_oid_id_pkix_on_pkinit_ms_san DATA
asn1_oid_id_pkix_on_pkinit_san DATA
asn1_oid_id_pkix_on_xmppAddr DATA
asn1_oid_id_pkix_pe_authorityInfoAccess DATA
asn1_oid_id_pkix_pe DATA
@@ -274,12 +289,16 @@ EXPORTS
copy_AD_LoginAlias
copy_AD_MANDATORY_FOR_KDC
copy_AlgorithmIdentifier
copy_AliasIA5String
copy_AliasPrintableString
copy_AliasUTF8String
copy_APOptions
copy_AP_REP
copy_AP_REQ
copy_AS_REP
copy_AS_REQ
copy_Attribute
copy_AttributeSet
copy_AttributeType
copy_AttributeTypeAndValue
copy_AttributeValue
@@ -402,7 +421,9 @@ EXPORTS
copy_HardwareModules
copy_HardwareSerialEntry
copy_heim_any
copy_HEIM_ANY
copy_heim_any_set
copy_HEIM_ANY_SET
copy_HostAddress
copy_HostAddresses
copy_ImplementedCompressAlgorithms
@@ -432,11 +453,11 @@ EXPORTS
copy_KeyIdentifier
copy_KeyTransRecipientInfo
copy_KeyUsage
copy_krb5int32
copy_Krb5Int32
copy_KRB5PrincipalName
copy_KRB5SignedPath
copy_KRB5SignedPathData
copy_krb5uint32
copy_Krb5UInt32
copy_KRB_CRED
copy_KrbCredInfo
copy_KRB_ERROR
@@ -532,6 +553,7 @@ EXPORTS
copy_PkinitSP80056AOtherInfo
copy_PkinitSuppPubInfo
copy_PKIXXmppAddr
copy_PolicyConstraints
copy_PolicyInformation
copy_PolicyMapping
copy_PolicyMappings
@@ -566,8 +588,11 @@ EXPORTS
copy_SignerIdentifier
copy_SignerInfo
copy_SignerInfos
copy_SingleAttribute
copy_SkipCerts
copy_SRVName
copy_StrengthOfFunction
copy_SubjectDirectoryAttributes
copy_SubjectInfoAccessSyntax
copy_SubjectKeyIdentifier
copy_SubjectPublicKeyInfo
@@ -599,6 +624,12 @@ EXPORTS
copy_VendorLoadErrorCode
copy_Version
copy_WrappedFirmwareKey
copy_X520CommonName
copy_X520LocalityName
copy_X520name
copy_X520OrganizationalUnitName
copy_X520OrganizationName
copy_X520StateOrProvinceName
copy_X690SampleChildInformation
copy_X690SampleDate
copy_X690SampleEmployeeNumber
@@ -612,12 +643,16 @@ EXPORTS
decode_AD_LoginAlias
decode_AD_MANDATORY_FOR_KDC
decode_AlgorithmIdentifier
decode_AliasIA5String
decode_AliasPrintableString
decode_AliasUTF8String
decode_APOptions
decode_AP_REP
decode_AP_REQ
decode_AS_REP
decode_AS_REQ
decode_Attribute
decode_AttributeSet
decode_AttributeType
decode_AttributeTypeAndValue
decode_AttributeValue
@@ -740,7 +775,9 @@ EXPORTS
decode_HardwareModules
decode_HardwareSerialEntry
decode_heim_any
decode_HEIM_ANY
decode_heim_any_set
decode_HEIM_ANY_SET
decode_HostAddress
decode_HostAddresses
decode_ImplementedCompressAlgorithms
@@ -770,11 +807,11 @@ EXPORTS
decode_KeyIdentifier
decode_KeyTransRecipientInfo
decode_KeyUsage
decode_krb5int32
decode_Krb5Int32
decode_KRB5PrincipalName
decode_KRB5SignedPath
decode_KRB5SignedPathData
decode_krb5uint32
decode_Krb5UInt32
decode_KRB_CRED
decode_KrbCredInfo
decode_KRB_ERROR
@@ -870,6 +907,7 @@ EXPORTS
decode_PkinitSP80056AOtherInfo
decode_PkinitSuppPubInfo
decode_PKIXXmppAddr
decode_PolicyConstraints
decode_PolicyInformation
decode_PolicyMapping
decode_PolicyMappings
@@ -904,8 +942,11 @@ EXPORTS
decode_SignerIdentifier
decode_SignerInfo
decode_SignerInfos
decode_SingleAttribute
decode_SkipCerts
decode_SRVName
decode_StrengthOfFunction
decode_SubjectDirectoryAttributes
decode_SubjectInfoAccessSyntax
decode_SubjectKeyIdentifier
decode_SubjectPublicKeyInfo
@@ -937,6 +978,12 @@ EXPORTS
decode_VendorLoadErrorCode
decode_Version
decode_WrappedFirmwareKey
decode_X520CommonName
decode_X520LocalityName
decode_X520name
decode_X520OrganizationalUnitName
decode_X520OrganizationName
decode_X520StateOrProvinceName
decode_X690SampleChildInformation
decode_X690SampleDate
decode_X690SampleEmployeeNumber
@@ -1042,9 +1089,27 @@ EXPORTS
der_parse_heim_oid
der_parse_hex_heim_integer
der_printable_string_cmp
der_print_bit_string
der_print_bmp_string
der_print_boolean
der_print_generalized_time
der_print_general_string
der_print_heim_integer
der_print_heim_oid
der_print_heim_oid_sym
der_print_hex_heim_integer
der_print_ia5_string
der_print_integer
der_print_integer64
der_print_octet_string
der_print_oid
der_print_printable_string
der_print_universal_string
der_print_unsigned
der_print_unsigned64
der_print_utctime
der_print_utf8string
der_print_visible_string
der_put_bit_string
der_put_bmp_string
der_put_boolean
@@ -1078,12 +1143,16 @@ EXPORTS
encode_AD_LoginAlias
encode_AD_MANDATORY_FOR_KDC
encode_AlgorithmIdentifier
encode_AliasIA5String
encode_AliasPrintableString
encode_AliasUTF8String
encode_APOptions
encode_AP_REP
encode_AP_REQ
encode_AS_REP
encode_AS_REQ
encode_Attribute
encode_AttributeSet
encode_AttributeType
encode_AttributeTypeAndValue
encode_AttributeValue
@@ -1206,7 +1275,9 @@ EXPORTS
encode_HardwareModules
encode_HardwareSerialEntry
encode_heim_any
encode_HEIM_ANY
encode_heim_any_set
encode_HEIM_ANY_SET
encode_HostAddress
encode_HostAddresses
encode_ImplementedCompressAlgorithms
@@ -1236,11 +1307,11 @@ EXPORTS
encode_KeyIdentifier
encode_KeyTransRecipientInfo
encode_KeyUsage
encode_krb5int32
encode_Krb5Int32
encode_KRB5PrincipalName
encode_KRB5SignedPath
encode_KRB5SignedPathData
encode_krb5uint32
encode_Krb5UInt32
encode_KRB_CRED
encode_KrbCredInfo
encode_KRB_ERROR
@@ -1336,6 +1407,7 @@ EXPORTS
encode_PkinitSP80056AOtherInfo
encode_PkinitSuppPubInfo
encode_PKIXXmppAddr
encode_PolicyConstraints
encode_PolicyInformation
encode_PolicyMapping
encode_PolicyMappings
@@ -1370,8 +1442,11 @@ EXPORTS
encode_SignerIdentifier
encode_SignerInfo
encode_SignerInfos
encode_SingleAttribute
encode_SkipCerts
encode_SRVName
encode_StrengthOfFunction
encode_SubjectDirectoryAttributes
encode_SubjectInfoAccessSyntax
encode_SubjectKeyIdentifier
encode_SubjectPublicKeyInfo
@@ -1403,6 +1478,12 @@ EXPORTS
encode_VendorLoadErrorCode
encode_Version
encode_WrappedFirmwareKey
encode_X520CommonName
encode_X520LocalityName
encode_X520name
encode_X520OrganizationalUnitName
encode_X520OrganizationName
encode_X520StateOrProvinceName
encode_X690SampleChildInformation
encode_X690SampleDate
encode_X690SampleEmployeeNumber
@@ -1417,12 +1498,16 @@ EXPORTS
free_AD_LoginAlias
free_AD_MANDATORY_FOR_KDC
free_AlgorithmIdentifier
free_AliasIA5String
free_AliasPrintableString
free_AliasUTF8String
free_APOptions
free_AP_REP
free_AP_REQ
free_AS_REP
free_AS_REQ
free_Attribute
free_AttributeSet
free_AttributeType
free_AttributeTypeAndValue
free_AttributeValue
@@ -1545,7 +1630,9 @@ EXPORTS
free_HardwareModules
free_HardwareSerialEntry
free_heim_any
free_HEIM_ANY
free_heim_any_set
free_HEIM_ANY_SET
free_HostAddress
free_HostAddresses
free_ImplementedCompressAlgorithms
@@ -1575,11 +1662,11 @@ EXPORTS
free_KeyIdentifier
free_KeyTransRecipientInfo
free_KeyUsage
free_krb5int32
free_Krb5Int32
free_KRB5PrincipalName
free_KRB5SignedPath
free_KRB5SignedPathData
free_krb5uint32
free_Krb5UInt32
free_KRB_CRED
free_KrbCredInfo
free_KRB_ERROR
@@ -1675,6 +1762,7 @@ EXPORTS
free_PkinitSP80056AOtherInfo
free_PkinitSuppPubInfo
free_PKIXXmppAddr
free_PolicyConstraints
free_PolicyInformation
free_PolicyMapping
free_PolicyMappings
@@ -1709,8 +1797,11 @@ EXPORTS
free_SignerIdentifier
free_SignerInfo
free_SignerInfos
free_SingleAttribute
free_SkipCerts
free_SRVName
free_StrengthOfFunction
free_SubjectDirectoryAttributes
free_SubjectInfoAccessSyntax
free_SubjectKeyIdentifier
free_SubjectPublicKeyInfo
@@ -1742,12 +1833,19 @@ EXPORTS
free_VendorLoadErrorCode
free_Version
free_WrappedFirmwareKey
free_X520CommonName
free_X520LocalityName
free_X520name
free_X520OrganizationalUnitName
free_X520OrganizationName
free_X520StateOrProvinceName
free_X690SampleChildInformation
free_X690SampleDate
free_X690SampleEmployeeNumber
free_X690SampleName
free_X690SamplePersonnelRecord
heim_any_cmp
HEIM_ANY_cmp
_heim_der_set_sort
_heim_fix_dce
_heim_len_int
@@ -1777,12 +1875,16 @@ EXPORTS
length_AD_LoginAlias
length_AD_MANDATORY_FOR_KDC
length_AlgorithmIdentifier
length_AliasIA5String
length_AliasPrintableString
length_AliasUTF8String
length_APOptions
length_AP_REP
length_AP_REQ
length_AS_REP
length_AS_REQ
length_Attribute
length_AttributeSet
length_AttributeType
length_AttributeTypeAndValue
length_AttributeValue
@@ -1905,7 +2007,9 @@ EXPORTS
length_HardwareModules
length_HardwareSerialEntry
length_heim_any
length_HEIM_ANY
length_heim_any_set
length_HEIM_ANY_SET
length_HostAddress
length_HostAddresses
length_ImplementedCompressAlgorithms
@@ -1935,11 +2039,11 @@ EXPORTS
length_KeyIdentifier
length_KeyTransRecipientInfo
length_KeyUsage
length_krb5int32
length_Krb5Int32
length_KRB5PrincipalName
length_KRB5SignedPath
length_KRB5SignedPathData
length_krb5uint32
length_Krb5UInt32
length_KRB_CRED
length_KrbCredInfo
length_KRB_ERROR
@@ -2035,6 +2139,7 @@ EXPORTS
length_PkinitSP80056AOtherInfo
length_PkinitSuppPubInfo
length_PKIXXmppAddr
length_PolicyConstraints
length_PolicyInformation
length_PolicyMapping
length_PolicyMappings
@@ -2069,8 +2174,11 @@ EXPORTS
length_SignerIdentifier
length_SignerInfo
length_SignerInfos
length_SingleAttribute
length_SkipCerts
length_SRVName
length_StrengthOfFunction
length_SubjectDirectoryAttributes
length_SubjectInfoAccessSyntax
length_SubjectKeyIdentifier
length_SubjectPublicKeyInfo
@@ -2102,6 +2210,12 @@ EXPORTS
length_VendorLoadErrorCode
length_Version
length_WrappedFirmwareKey
length_X520CommonName
length_X520LocalityName
length_X520name
length_X520OrganizationalUnitName
length_X520OrganizationName
length_X520StateOrProvinceName
length_X690SampleChildInformation
length_X690SampleDate
length_X690SampleEmployeeNumber

View File

@@ -123,7 +123,8 @@ struct getargs args[] = {
"the ASN.1 module instead of topologically sorting types. This "
"is useful for comparing output to earlier compiler versions.",
NULL },
{ "parse-units", 0, arg_negative_flag, &parse_units_flag, NULL, NULL },
{ "parse-units", 0, arg_negative_flag, &parse_units_flag,
"Do not generate roken-style units", NULL },
{ "type-file", 0, arg_string, &type_file_string,
"Name of a C header file to generate includes of for base types",
"C-HEADER-FILE" },

View File

@@ -46,9 +46,7 @@
#include "pkcs9_asn1.h"
#include "pkinit_asn1.h"
#include "rfc2459_asn1.h"
#include "rfc4043_asn1.h"
#include "rfc4108_asn1.h"
#include "tcg_asn1.h"
struct sym_oid {
@@ -73,9 +71,7 @@ static const struct sym_oid sym_oids[] = {
#include "pkcs9_asn1_oids.x"
#include "pkinit_asn1_oids.x"
#include "rfc2459_asn1_oids.x"
#include "rfc4043_asn1_oids.x"
#include "rfc4108_asn1_oids.x"
#include "tcg_asn1_oids.x"
};
static size_t num_sym_oids = sizeof(sym_oids) / sizeof(sym_oids[0]);

View File

@@ -6,7 +6,7 @@ BEGIN
IMPORTS ContentInfo FROM cms
DigestInfo FROM rfc2459
heim_any, heim_any_set FROM heim;
HEIM_ANY, HEIM_ANY_SET FROM heim;
-- The PFX PDU
@@ -50,14 +50,14 @@ PKCS12-AuthenticatedSafe ::= SEQUENCE OF ContentInfo
PKCS12-Attribute ::= SEQUENCE {
attrId OBJECT IDENTIFIER,
attrValues -- SET OF -- heim_any_set
attrValues -- SET OF -- HEIM_ANY_SET
}
PKCS12-Attributes ::= SET OF PKCS12-Attribute
PKCS12-SafeBag ::= SEQUENCE {
bagId OBJECT IDENTIFIER,
bagValue [0] heim_any,
bagValue [0] HEIM_ANY,
bagAttributes PKCS12-Attributes OPTIONAL
}
@@ -65,7 +65,7 @@ PKCS12-SafeContents ::= SEQUENCE OF PKCS12-SafeBag
PKCS12-CertBag ::= SEQUENCE {
certType OBJECT IDENTIFIER,
certValue [0] heim_any
certValue [0] HEIM_ANY
}
PKCS12-PBEParams ::= SEQUENCE {

View File

@@ -5,7 +5,7 @@ PKINIT DEFINITIONS ::= BEGIN
IMPORTS EncryptionKey, PrincipalName, Realm, KerberosTime, Checksum, Ticket FROM krb5
IssuerAndSerialNumber FROM cms
SubjectPublicKeyInfo, AlgorithmIdentifier FROM rfc2459
heim_any FROM heim;
HEIM_ANY FROM heim;
id-pkinit OBJECT IDENTIFIER ::=
{ iso (1) org (3) dod (6) internet (1) security (5)
@@ -96,11 +96,6 @@ AuthPack ::= SEQUENCE {
TD-TRUSTED-CERTIFIERS ::= ExternalPrincipalIdentifiers
TD-INVALID-CERTIFICATES ::= ExternalPrincipalIdentifiers
KRB5PrincipalName ::= SEQUENCE {
realm [0] Realm,
principalName [1] PrincipalName
}
AD-INITIAL-VERIFIED-CAS ::= SEQUENCE OF ExternalPrincipalIdentifier
DHRepInfo ::= SEQUENCE {
@@ -150,7 +145,7 @@ AuthPack-Win2k ::= SEQUENCE {
TrustedCA-Win2k ::= CHOICE {
caName [1] heim_any,
caName [1] HEIM_ANY,
issuerAndSerial [2] IssuerAndSerialNumber
}
@@ -178,8 +173,8 @@ ReplyKeyPack-Win2k ::= SEQUENCE {
}
PA-PK-AS-REP-BTMM ::= SEQUENCE {
dhSignedData [0] heim_any OPTIONAL,
encKeyPack [1] heim_any OPTIONAL
dhSignedData [0] HEIM_ANY OPTIONAL,
encKeyPack [1] HEIM_ANY OPTIONAL
}

View File

@@ -9,7 +9,13 @@
RFC2459 DEFINITIONS ::= BEGIN
IMPORTS heim_any FROM heim;
IMPORTS HEIM_ANY FROM heim
PrincipalName, Realm FROM krb5;
-- For OtherName we really want to also import:
-- KRB5PrincipalName FROM pkinit
-- PermanentIdentifier FROM rfc4043
-- HardwareModuleName FROM rfc4108;
-- But we can't because that creates circular dependencies.
Version ::= INTEGER {
rfc3280_version_1(0),
@@ -169,6 +175,10 @@ id-Userid OBJECT IDENTIFIER ::=
id-domainComponent OBJECT IDENTIFIER ::=
{ 0 9 2342 19200300 100 1 25 }
id-at-emailAddress AttributeType ::=
{ iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 9 1 }
-- rfc3280
@@ -176,12 +186,12 @@ id-x509-ce OBJECT IDENTIFIER ::= {joint-iso-ccitt(2) ds(5) 29}
AlgorithmIdentifier ::= SEQUENCE {
algorithm OBJECT IDENTIFIER,
parameters heim_any OPTIONAL
parameters HEIM_ANY OPTIONAL
}
AttributeType ::= OBJECT IDENTIFIER
AttributeValue ::= heim_any
AttributeValue ::= HEIM_ANY
DirectoryString ::= CHOICE {
ia5String IA5String,
@@ -204,7 +214,18 @@ AttributeTypeAndValue ::= SEQUENCE {
value DirectoryString
}
RelativeDistinguishedName ::= SET OF AttributeTypeAndValue
-- RDNs really should be SET OF SingleAttribute per the RFCs, but making that
-- change will affect lib/hx509 code, so we'll wait. The issue is that there
-- is code in lib/hx509 and in lib/asn1/check-gen.c that assumes that the
-- `value` of an rdn is a `DirectoryString` and not an open type.
--
-- Also, it's really not worth making this change, as a) it will increase the
-- amount of code needed in lib/hx509, and b) it really is useful to be able to
-- assume RDN values are ultimately only strings, c) we don't have any attrs
-- for RDNs that aren't strings, and d) the non-string attributes from TCG that
-- are used in SubjectDirectoryAttributes will never be used here (so we hope).
--
RelativeDistinguishedName ::= SET OF AttributeTypeAndValue -- XXX SingleAttribute
RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
@@ -231,10 +252,48 @@ SubjectPublicKeyInfo ::= SEQUENCE {
subjectPublicKey BIT STRING
}
Extension ::= SEQUENCE {
extnID OBJECT IDENTIFIER,
critical BOOLEAN OPTIONAL, -- DEFAULT FALSE XXX
extnValue OCTET STRING
-- XXX Should be _OTHER-NAME ::= _TYPE-IDENTIFIER
_OTHER-NAME ::= CLASS {
&id OBJECT IDENTIFIER UNIQUE,
&Type
}
OtherName{_OTHER-NAME:OtherNameSet} ::= SEQUENCE {
type-id _OTHER-NAME.&id({OtherNameSet}),
value [0] _OTHER-NAME.&Type({OtherNameSet}{@type-id})
}
_ATTRIBUTE ::= CLASS {
&id OBJECT IDENTIFIER UNIQUE,
&Type OPTIONAL,
-- &equality-match MATCHING-RULE OPTIONAL,
&minCount INTEGER DEFAULT 1,
&maxCount INTEGER OPTIONAL
}
SingleAttribute{_ATTRIBUTE:AttrSet} ::= SEQUENCE {
type _ATTRIBUTE.&id({AttrSet}),
value _ATTRIBUTE.&Type({AttrSet}{@type})
}
AttributeSet{_ATTRIBUTE:AttrSet} ::= SEQUENCE {
type _ATTRIBUTE.&id({AttrSet}),
values SET --SIZE (1..MAX)-- OF _ATTRIBUTE.&Type({AttrSet}{@type})
}
_EXTENSION ::= CLASS {
&id OBJECT IDENTIFIER UNIQUE,
&ExtnType,
&Critical BOOLEAN DEFAULT FALSE
}
Extension{_EXTENSION:ExtensionSet} ::= SEQUENCE {
extnID _EXTENSION.&id({ExtensionSet}),
critical BOOLEAN
-- (EXTENSION.&Critical({ExtensionSet}{@extnID}))
DEFAULT FALSE,
extnValue OCTET STRING (CONTAINING
_EXTENSION.&ExtnType({ExtensionSet}{@extnID}))
}
Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension
@@ -285,16 +344,8 @@ DHParameter ::= SEQUENCE {
DHPublicKey ::= INTEGER
OtherName ::= SEQUENCE {
type-id OBJECT IDENTIFIER,
value [0] EXPLICIT heim_any
}
GeneralName ::= CHOICE {
otherName [0] IMPLICIT -- OtherName -- SEQUENCE {
type-id OBJECT IDENTIFIER,
value [0] EXPLICIT heim_any
},
otherName [0] IMPLICIT OtherName,
rfc822Name [1] IMPLICIT IA5String,
dNSName [2] IMPLICIT IA5String,
-- x400Address [3] IMPLICIT ORAddress,--
@@ -336,7 +387,7 @@ PolicyQualifierId ::= OBJECT IDENTIFIER -- ( id-qt-cps | id-qt-unotice )
PolicyQualifierInfo ::= SEQUENCE {
policyQualifierId PolicyQualifierId,
qualifier heim_any -- ANY DEFINED BY policyQualifierId
qualifier HEIM_ANY -- ANY DEFINED BY policyQualifierId
}
PolicyQualifierInfos ::= SEQUENCE SIZE (1..MAX) OF PolicyQualifierInfo
@@ -400,18 +451,18 @@ SubjectKeyIdentifier ::= KeyIdentifier
id-x509-ce-basicConstraints OBJECT IDENTIFIER ::= { id-x509-ce 19 }
BasicConstraints ::= SEQUENCE {
cA BOOLEAN OPTIONAL -- DEFAULT FALSE --,
cA BOOLEAN DEFAULT FALSE,
pathLenConstraint INTEGER (0..4294967295) OPTIONAL
}
id-x509-ce-nameConstraints OBJECT IDENTIFIER ::= { id-x509-ce 30 }
BaseDistance ::= INTEGER -- (0..MAX) --
BaseDistance ::= INTEGER (0..4294967295)
GeneralSubtree ::= SEQUENCE {
base GeneralName,
minimum [0] IMPLICIT -- BaseDistance -- INTEGER OPTIONAL -- DEFAULT 0 --,
maximum [1] IMPLICIT -- BaseDistance -- INTEGER OPTIONAL
minimum [0] IMPLICIT BaseDistance DEFAULT 0,
maximum [1] IMPLICIT BaseDistance OPTIONAL
}
GeneralSubtrees ::= SEQUENCE -- SIZE (1..MAX) -- OF GeneralSubtree
@@ -462,9 +513,9 @@ DistributionPointName ::= CHOICE {
}
DistributionPoint ::= SEQUENCE {
distributionPoint [0] IMPLICIT heim_any -- DistributionPointName -- OPTIONAL,
reasons [1] IMPLICIT heim_any -- DistributionPointReasonFlags -- OPTIONAL,
cRLIssuer [2] IMPLICIT heim_any -- GeneralNames -- OPTIONAL
distributionPoint [0] IMPLICIT HEIM_ANY -- DistributionPointName -- OPTIONAL,
reasons [1] IMPLICIT HEIM_ANY -- DistributionPointReasonFlags -- OPTIONAL,
cRLIssuer [2] IMPLICIT HEIM_ANY -- GeneralNames -- OPTIONAL
}
CRLDistributionPoints ::= SEQUENCE SIZE (1..MAX) OF DistributionPoint
@@ -596,6 +647,36 @@ id-pkix-on OBJECT IDENTIFIER ::= { id-pkix 8 }
id-pkix-on-xmppAddr OBJECT IDENTIFIER ::= { id-pkix-on 5 }
id-pkix-on-dnsSRV OBJECT IDENTIFIER ::= { id-pkix-on 7 }
-- From RFC4108
id-pkix-on-hardwareModuleName OBJECT IDENTIFIER ::= { id-pkix-on 4 }
HardwareModuleName ::= SEQUENCE {
hwType OBJECT IDENTIFIER,
hwSerialNum OCTET STRING
}
-- XXX Not really the right name
id-pkix-on-pkinit-san OBJECT IDENTIFIER ::=
{ iso(1) org(3) dod(6) internet(1) security(5) kerberosv5(2)
x509-sanan(2) }
KRB5PrincipalName ::= SEQUENCE {
realm [0] Realm,
principalName [1] PrincipalName
}
-- From RFC4043:
-- Permanent identifier Object Identifier and Syntax
id-pkix-on-permanentIdentifier OBJECT IDENTIFIER ::= { id-pkix-on 3 }
PermanentIdentifier ::= SEQUENCE {
identifierValue UTF8String OPTIONAL,
-- if absent, use the serialNumber attribute
-- if there is a single such attribute present
-- in the subject DN
assigner OBJECT IDENTIFIER OPTIONAL
-- if absent, the assigner is
-- the certificate issuer
}
-- EKUs
id-pkix-kp OBJECT IDENTIFIER ::= { id-pkix 3 }
id-pkix-kp-serverAuth OBJECT IDENTIFIER ::= { id-pkix-kp 1 }
@@ -634,7 +715,6 @@ id-msft-kp-msSmartcardLogin OBJECT IDENTIFIER ::= { id-msft 20 2 2 }
id-msft-kp-msUPN OBJECT IDENTIFIER ::= { id-msft 20 2 3 }
id-pkix-pe OBJECT IDENTIFIER ::= { id-pkix 1 }
id-pkix-pe-authorityInfoAccess OBJECT IDENTIFIER ::= { id-pkix-pe 1 }
AccessDescription ::= SEQUENCE {
@@ -669,6 +749,350 @@ ProxyCertInfo ::= SEQUENCE {
proxyPolicy ProxyPolicy
}
-- TCG contents:
-- See tcg.asn1 for commentary.
--TCG specific OIDs
tcg OBJECT IDENTIFIER ::= {joint-iso-itu-t(2) international-organizations(23) tcg(133)}
tcg-attribute OBJECT IDENTIFIER ::= {tcg 2}
tcg-kp OBJECT IDENTIFIER ::= {tcg 8}
--TCG Attribute OIDs
tcg-at-tpmManufacturer OBJECT IDENTIFIER ::= {tcg-attribute 1}
tcg-at-tpmModel OBJECT IDENTIFIER ::= {tcg-attribute 2}
tcg-at-tpmVersion OBJECT IDENTIFIER ::= {tcg-attribute 3}
tcg-at-tpmSpecification OBJECT IDENTIFIER ::= {tcg-attribute 16}
tcg-at-tpmSecurityAssertions OBJECT IDENTIFIER ::= {tcg-attribute 18}
--TCG Attribute objects
at-TPMSecurityAssertions _ATTRIBUTE ::= { &Type TPMSecurityAssertions, &id tcg-at-tpmSecurityAssertions }
at-TPMManufacturer _ATTRIBUTE ::= { &Type AliasUTF8String, --(SIZE (1..STRMAX))-- &id tcg-at-tpmManufacturer }
at-TPMModel _ATTRIBUTE ::= { &Type AliasUTF8String, --(SIZE (1..STRMAX))-- &id tcg-at-tpmModel }
at-TPMVersion _ATTRIBUTE ::= { &Type AliasUTF8String, --(SIZE (1..STRMAX))-- &id tcg-at-tpmVersion }
at-TPMSpecification _ATTRIBUTE ::= { &Type TPMSpecification, &id tcg-at-tpmSpecification }
--TCG Extended Key Usage OIDs
tcg-kp-EKCertificate OBJECT IDENTIFIER ::= {tcg-kp 1}
-- OIDs not in the module in TCG_IWG_EKCredentialProfile_v2p3_r2_pub but in
-- TCG_IWG_DevID_v1r2_02dec2020 (missing arc names not mentioned in the TCG
-- specs):
tcg-tpm20 OBJECT IDENTIFIER ::= {tcg 1 2} -- this OID is not named in the TCG specs
tcg-on-ekPermIdSha256 OBJECT IDENTIFIER ::= {tcg 12 1} -- assigner value for PermanentIdentifier SAN
tcg-cap-verifiedTPMResidency OBJECT IDENTIFIER ::= {tcg 11 1 1} -- policy OID
tcg-cap-verifiedTPMFixed OBJECT IDENTIFIER ::= {tcg 11 1 2} -- policy OID
tcg-cap-verifiedTPMRestricted OBJECT IDENTIFIER ::= {tcg 11 1 3} -- policy OID
EKGenerationType ::= ENUMERATED {
ekgt-internal (0),
ekgt-injected (1),
ekgt-internalRevocable(2),
ekgt-injectedRevocable(3)
}
EKGenerationLocation ::= ENUMERATED {
tpmManufacturer (0),
platformManufacturer (1),
ekCertSigner (2)
}
EKCertificateGenerationLocation ::= EKGenerationLocation -- XXX
EvaluationAssuranceLevel ::= ENUMERATED {
ealevell (1),
ealevel2 (2),
ealevel3 (3),
ealevel4 (4),
ealevel5 (5),
ealevel6 (6),
ealevel7 (7)
}
SecurityLevel ::= ENUMERATED {
sllevel1 (1),
sllevel2 (2),
sllevel3 (3),
sllevel4 (4)
}
StrengthOfFunction ::= ENUMERATED {
sof-basic (0),
sof-medium (1),
sof-high (2)
}
URIReference ::= SEQUENCE {
uniformResourceIdentifier IA5String, -- (SIZE (1..URIMAX))
hashAlgorithm AlgorithmIdentifier OPTIONAL,
hashValue BIT STRING OPTIONAL
}
EvaluationStatus ::= ENUMERATED {
designedToMeet (0),
evaluationInProgress (1),
evaluationCompleted (2)
}
--tcg specification attributes for tpm
TPMSpecification ::= SEQUENCE {
family UTF8String, -- (SIZE (1..STRMAX))
level INTEGER (0..4294967295),
revision INTEGER (0..4294967295),
...
}
--common criteria evaluation
CommonCriteriaMeasures ::= SEQUENCE {
version IA5String, -- (SIZE (1..STRMAX)) “2.2” or “3.1”;future syntax defined by CC
assurancelevel EvaluationAssuranceLevel,
evaluationStatus EvaluationStatus,
plus BOOLEAN DEFAULT FALSE,
strengthOfFunction [0] IMPLICIT StrengthOfFunction OPTIONAL,
profileOid [1] IMPLICIT OBJECT IDENTIFIER OPTIONAL,
profileUri [2] IMPLICIT URIReference OPTIONAL,
targetOid [3] IMPLICIT OBJECT IDENTIFIER OPTIONAL,
targetUri [4] IMPLICIT URIReference OPTIONAL,
...
}
--fips evaluation
FIPSLevel ::= SEQUENCE {
version IA5String, -- (SIZE (1..STRMAX)) “140-1” or “140-2”
level SecurityLevel,
plus BOOLEAN DEFAULT FALSE,
...
}
--tpm security assertions
TPMVersion ::= INTEGER { tpm-v1(0) }
TPMSecurityAssertions ::= SEQUENCE {
version TPMVersion DEFAULT 0, -- v1
fieldUpgradable BOOLEAN DEFAULT FALSE,
ekGenerationType [0] IMPLICIT EKGenerationType OPTIONAL,
ekGenerationLocation [1] IMPLICIT EKGenerationLocation OPTIONAL,
ekCertificateGenerationLocation [2] IMPLICIT EKCertificateGenerationLocation OPTIONAL,
-- These two are marked IMPLICIT, but...
ccInfo [3] CommonCriteriaMeasures OPTIONAL,
fipsLevel [4] FIPSLevel OPTIONAL,
iso9000Certified [5] IMPLICIT BOOLEAN DEFAULT FALSE,
iso9000Uri IA5String OPTIONAL, -- (SIZE (1..URIMAX))
...
}
-- Back to OtherName, SingleAttribute, AttributeSet, and Extension
-- XXX Not really the right name for this OID:
id-pkix-on-pkinit-ms-san OBJECT IDENTIFIER ::=
{ iso(1) org(3) dod(6) internet(1) private(4)
enterprise(1) microsoft(311) 20 2 3 }
-- XXX Work around bug (where we don't know the names of universal types in the
-- template backend) by creating aliases for universal types we use in IOS
-- objects.
AliasUTF8String ::= UTF8String
AliasIA5String ::= UTF8String
AliasPrintableString ::= PrintableString
on-xmppAddr _OTHER-NAME ::= { &id id-pkix-on-xmppAddr, &Type AliasUTF8String }
on-dnsSRV _OTHER-NAME ::= { &id id-pkix-on-dnsSRV, &Type AliasIA5String }
on-hardwareModuleName _OTHER-NAME ::= {
&id id-pkix-on-hardwareModuleName,
&Type HardwareModuleName
}
on-permanentIdentifier _OTHER-NAME ::= {
&id id-pkix-on-permanentIdentifier,
&Type PermanentIdentifier
}
on-krb5PrincipalName _OTHER-NAME ::= {
&id id-pkix-on-pkinit-san,
&Type KRB5PrincipalName
}
on-pkinit-ms-san _OTHER-NAME ::= {
&id id-pkix-on-pkinit-ms-san,
&Type AliasUTF8String
}
KnownOtherNameTypes _OTHER-NAME ::= {
on-xmppAddr
| on-dnsSRV
| on-hardwareModuleName
| on-permanentIdentifier
| on-krb5PrincipalName
| on-pkinit-ms-san
}
OtherName ::= OtherName{KnownOtherNameTypes}
X520name ::= DirectoryString --{ub-name}
X520CommonName ::= DirectoryString --{ub-common-name}
X520LocalityName ::= DirectoryString --{ub-locality-name}
X520OrganizationName ::= DirectoryString --{ub-organization-name}
X520StateOrProvinceName ::= DirectoryString --{ub-state-name}
X520OrganizationalUnitName ::= DirectoryString --{ub-organizational-unit-name}
at-name _ATTRIBUTE ::= { &Type X520name, &id id-at-name }
at-surname _ATTRIBUTE ::= { &Type X520name, &id id-at-surname }
at-givenName _ATTRIBUTE ::= { &Type X520name, &id id-at-givenName }
at-initials _ATTRIBUTE ::= { &Type X520name, &id id-at-initials }
at-generationQualifier _ATTRIBUTE ::= { &Type X520name, &id id-at-generationQualifier }
at-x520CommonName _ATTRIBUTE ::= {&Type X520CommonName, &id id-at-commonName }
at-x520LocalityName _ATTRIBUTE ::= { &Type X520LocalityName, &id id-at-localityName }
at-x520StateOrProvinceName _ATTRIBUTE ::= { &Type DirectoryString --{ub-state-name}--, &id id-at-stateOrProvinceName }
at-x520OrganizationName _ATTRIBUTE ::= { &Type DirectoryString --{ub-organization-name}--, &id id-at-organizationName }
at-x520OrganizationalUnitName _ATTRIBUTE ::= { &Type DirectoryString --{ub-organizational-unit-name}--, &id id-at-organizationalUnitName }
at-x520Title _ATTRIBUTE ::= { &Type DirectoryString --{ub-title}--, &id id-at-title }
at-x520dnQualifier _ATTRIBUTE ::= { &Type AliasPrintableString, &id id-at-dnQualifier }
at-x520countryName _ATTRIBUTE ::= { &Type AliasPrintableString --(SIZE (2))--, &id id-at-countryName }
at-x520SerialNumber _ATTRIBUTE ::= {&Type AliasPrintableString --(SIZE (1..ub-serial-number))--, &id id-at-serialNumber }
at-x520Pseudonym _ATTRIBUTE ::= { &Type DirectoryString --{ub-pseudonym}--, &id id-at-pseudonym }
at-domainComponent _ATTRIBUTE ::= { &Type AliasIA5String, &id id-domainComponent }
at-emailAddress _ATTRIBUTE ::= { &Type AliasIA5String --(SIZE (1..ub-emailaddress-length))--, &id id-at-emailAddress }
SupportedAttributes _ATTRIBUTE ::= {
at-name
| at-surname
| at-givenName
| at-initials
| at-generationQualifier
| at-x520CommonName
| at-x520LocalityName
| at-x520StateOrProvinceName
| at-x520OrganizationName
| at-x520OrganizationalUnitName
| at-x520Title
| at-x520dnQualifier
| at-x520countryName
| at-x520SerialNumber
| at-x520Pseudonym
| at-domainComponent
| at-emailAddress
| at-TPMSecurityAssertions
| at-TPMManufacturer
| at-TPMModel
| at-TPMVersion
| at-TPMSpecification
}
-- Currently this crashes the ASN.1 compiler because it knows how to deal with
-- contents constraints that use ObjectClassFieldType references, but it
-- doesn't know how to deal with those as SEQUENCE/SET member types.
--
SingleAttribute ::= SingleAttribute{SupportedAttributes}
AttributeSet ::= AttributeSet{SupportedAttributes}
SubjectDirectoryAttributes ::= SEQUENCE SIZE (1..MAX) OF AttributeSet
ext-AuthorityKeyIdentifier _EXTENSION ::= {
&id id-x509-ce-authorityKeyIdentifier,
&Critical FALSE,
&ExtnType AuthorityKeyIdentifier
}
ext-KeyUsage _EXTENSION ::= {
&id id-x509-ce-keyUsage,
&Critical FALSE,
&ExtnType KeyUsage
}
ext-SubjectKeyIdentifier _EXTENSION ::= {
&id id-x509-ce-subjectKeyIdentifier,
&Critical FALSE,
&ExtnType SubjectKeyIdentifier
}
ext-PrivateKeyUsagePeriod _EXTENSION ::= {
&id id-x509-ce-privateKeyUsagePeriod,
&Critical FALSE,
&ExtnType PrivateKeyUsagePeriod
}
ext-CertificatePolicies _EXTENSION ::= {
&id id-x509-ce-certificatePolicies,
&Critical FALSE,
&ExtnType CertificatePolicies
}
ext-PolicyMappings _EXTENSION ::= {
&id id-x509-ce-policyMappings,
&Critical FALSE,
&ExtnType PolicyMappings
}
ext-SubjectAltName _EXTENSION ::= {
&id id-x509-ce-subjectAltName,
&Critical FALSE,
&ExtnType GeneralNames
}
ext-IssuerAltName _EXTENSION ::= {
&id id-x509-ce-issuerAltName,
&Critical FALSE,
&ExtnType GeneralNames
}
ext-SubjectDirectoryAttributes _EXTENSION ::= {
&id id-x509-ce-subjectDirectoryAttributes,
&Critical FALSE,
&ExtnType SubjectDirectoryAttributes
}
ext-BasicConstraints _EXTENSION ::= {
&id id-x509-ce-basicConstraints,
&Critical FALSE,
&ExtnType BasicConstraints
}
ext-NameConstraints _EXTENSION ::= {
&id id-x509-ce-nameConstraints,
&Critical FALSE,
&ExtnType NameConstraints
}
SkipCerts ::= INTEGER (0..4294967295)
PolicyConstraints ::= SEQUENCE {
requireExplicitPolicy [0] IMPLICIT SkipCerts OPTIONAL,
inhibitPolicyMapping [1] IMPLICIT SkipCerts OPTIONAL
}
ext-PolicyConstraints _EXTENSION ::= {
&id id-x509-ce-policyConstraints,
&Critical FALSE,
&ExtnType PolicyConstraints
}
ext-ExtKeyUsage _EXTENSION ::= {
&id id-x509-ce-extKeyUsage,
&Critical FALSE,
&ExtnType ExtKeyUsage
}
ext-CRLDistributionPoints _EXTENSION ::= {
&id id-x509-ce-cRLDistributionPoints,
&Critical FALSE,
&ExtnType CRLDistributionPoints
}
ext-InhibitAnyPolicy _EXTENSION ::= {
&id id-x509-ce-inhibitAnyPolicy,
&Critical FALSE,
&ExtnType SkipCerts
}
ext-FreshestCRL _EXTENSION ::= {
&id id-x509-ce-freshestCRL,
&Critical FALSE,
&ExtnType CRLDistributionPoints
}
ext-AuthorityInfoAccess _EXTENSION ::= {
&id id-pkix-pe-authorityInfoAccess,
&Critical FALSE,
&ExtnType AuthorityInfoAccessSyntax
}
ext-SubjectInfoAccessSyntax _EXTENSION ::= {
&id id-pkix-pe-subjectInfoAccess,
&Critical FALSE,
&ExtnType SubjectInfoAccessSyntax
}
CertExtensions _EXTENSION ::= {
ext-AuthorityKeyIdentifier
| ext-SubjectKeyIdentifier
| ext-KeyUsage
| ext-PrivateKeyUsagePeriod
| ext-CertificatePolicies
| ext-PolicyMappings
| ext-SubjectAltName
| ext-IssuerAltName
| ext-SubjectDirectoryAttributes
| ext-BasicConstraints
| ext-NameConstraints
| ext-PolicyConstraints
| ext-ExtKeyUsage
| ext-CRLDistributionPoints
| ext-InhibitAnyPolicy
| ext-FreshestCRL
| ext-AuthorityInfoAccess
| ext-SubjectInfoAccessSyntax
}
Extension ::= Extension { CertExtensions }
--- U.S. Federal PKI Common Policy Framework
-- Card Authentication key
id-uspkicommon-card-id OBJECT IDENTIFIER ::= { 2 16 840 1 101 3 6 6 }

View File

@@ -1,30 +0,0 @@
PKIXpermanentidentifier88 {iso(1) identified-organization(3) dod(6)
internet(1) security(5) mechanisms(5) pkix(7) id-mod(0)
id-mod-perm-id-88(28) }
DEFINITIONS EXPLICIT TAGS ::=
BEGIN
-- EXPORTS ALL --
-- IMPORTS id-pkix FROM rfc2459; but asn1_compile doesn't handle this
-- Permanent identifier Object Identifier and Syntax
id-on OBJECT IDENTIFIER ::= { iso(1) identified-organization(3)
dod(6) internet(1) security(5) mechanisms(5) pkix(7) 8 }
id-on-permanentIdentifier OBJECT IDENTIFIER ::= { id-on 3 }
PermanentIdentifier ::= SEQUENCE {
identifierValue UTF8String OPTIONAL,
-- if absent, use the serialNumber attribute
-- if there is a single such attribute present
-- in the subject DN
assigner OBJECT IDENTIFIER OPTIONAL
-- if absent, the assigner is
-- the certificate issuer
}
END

View File

@@ -5,6 +5,9 @@ CMSFirmwareWrapper
DEFINITIONS IMPLICIT TAGS ::= BEGIN
IMPORTS
-- We moved HardwareModuleName to avoid circular dependencies if
-- we have to have rfc2459 import it from here so we can define an
-- object set of OTHER-NAME class.
EnvelopedData
FROM cms -- [CMS]
{ iso(1) member-body(2) us(840) rsadsi(113549)
@@ -195,8 +198,10 @@ id-on-hardwareModuleName OBJECT IDENTIFIER ::= {
iso(1) identified-organization(3) dod(6) internet(1) security(5)
mechanisms(5) pkix(7) on(8) 4 }
HardwareModuleName ::= SEQUENCE {
hwType OBJECT IDENTIFIER,
hwSerialNum OCTET STRING }
-- Moved to rfc2459.asn1 so we can have the OtherName type decode it
-- automatically:
--HardwareModuleName ::= SEQUENCE {
-- hwType OBJECT IDENTIFIER,
-- hwSerialNum OCTET STRING }
END

View File

@@ -68,6 +68,8 @@ enum typetype {
typedef enum typetype Typetype;
struct type;
struct value;
struct typereference;
struct value {
enum { booleanvalue,
@@ -82,6 +84,7 @@ struct value {
char *stringvalue;
struct objid *objectidentifiervalue;
} u;
struct symbol *s;
};
struct member {
@@ -117,15 +120,82 @@ struct range {
int64_t max;
};
enum ctype { CT_CONTENTS, CT_USER } ;
enum ctype { CT_CONTENTS, CT_USER, CT_TABLE_CONSTRAINT } ;
struct constraint_spec;
struct iosclassfield {
char *name;
struct type *type;
struct value *defval;
HEIM_TAILQ_ENTRY(iosclassfield) fields;
unsigned long id;
unsigned int optional:1;
unsigned int unique:1;
};
typedef struct iosclassfield Field;
HEIM_TAILQ_HEAD(fieldhead, iosclassfield);
struct iosobjectfield {
char *name;
struct type *type;
struct value *value;
HEIM_TAILQ_ENTRY(iosobjectfield) objfields;
unsigned long id;
};
typedef struct iosobjectfield ObjectField;
HEIM_TAILQ_HEAD(objfieldhead, iosobjectfield);
struct iosclass {
struct symbol *symbol;
struct fieldhead *fields;
unsigned long id;
};
typedef struct iosclass IOSClass;
struct iosobject {
struct symbol *symbol;
struct objfieldhead *objfields;
ObjectField *typeidf;
IOSClass *iosclass;
HEIM_TAILQ_ENTRY(iosobject) objects;
unsigned long id;
unsigned int ellipsis:1;
unsigned int optional:1;
};
typedef struct iosobject IOSObject;
HEIM_TAILQ_HEAD(objectshead, iosobject);
struct iosobjectset {
struct symbol *symbol;
IOSClass *iosclass;
struct objectshead *objects;
unsigned long id;
};
typedef struct iosobjectset IOSObjectSet;
struct typereference {
/*
* For now we don't support link fields, so we don't support chains of more
* than one field.
*/
IOSClass *iosclass;
Field *field;
};
struct type {
Typetype type;
struct memhead *members;
struct symbol *symbol;
struct type *subtype;
struct typereference typeref; /* For type fields */
IOSClass *formal_parameter;
IOSObjectSet *actual_parameter;
struct tagtype tag;
struct range *range;
struct constraint_spec *constraint;
@@ -134,12 +204,18 @@ struct type {
typedef struct type Type;
struct component_relation_constraint {
char *objectname;
char *membername;
};
struct constraint_spec {
enum ctype ctype;
union {
struct {
Type *type;
struct value *encoding;
struct component_relation_constraint crel;
} content;
} u;
};
@@ -153,13 +229,17 @@ struct objid {
struct symbol {
char *name;
char *gen_name;
enum { SUndefined, SValue, Stype } stype;
enum { SUndefined, SValue, Stype, Sparamtype, Sclass, Sobj, Sobjset } stype;
struct value *value;
Type *type;
IOSClass *iosclass;
IOSObject *object;
IOSObjectSet *objectset;
HEIM_TAILQ_ENTRY(symbol) symlist;
unsigned int emitted_declaration:1;
unsigned int emitted_definition:1;
unsigned int emitted_tag_enums:1;
unsigned int emitted_template:1;
};
typedef struct symbol Symbol;

View File

@@ -1,8 +1,5 @@
TCG DEFINITIONS ::= BEGIN
IMPORTS AlgorithmIdentifier FROM rfc2459;
-- BEGIN Heimdal commentary
--
-- Copy-pasted from section 4 of
@@ -10,12 +7,17 @@ IMPORTS AlgorithmIdentifier FROM rfc2459;
-- https://trustedcomputinggroup.org/wp-content/uploads/Credential_Profile_EK_V2.0_R14_published.pdf
-- and adjusted to compile as follows:
--
-- - Due to limitations of the Heimdal compiler we've moved all of this
-- module's contents to rfc2459.asn1.
--
-- - Extensibility markers added to all SEQUENCEs as per the TCG's spec they
-- reserve the right to add fields in the future.
-- - Information Object System annotations commented out (Heimdal does not
-- support them)
--
-- - Types sorted topologically (at the time I did that the Heimdal ASN.1
-- compiler wouldn't do that on its own)
--
-- - Two otherwise equal ENUMERATED types share a definition now (at the time
-- the Heimdal ASN.1 compiler did not prefix labels of ENUMERATED types)
--
@@ -37,123 +39,4 @@ IMPORTS AlgorithmIdentifier FROM rfc2459;
--
-- END Heimdal commentary (though some minor Heimdal commentary appears below)
--TCG specific OIDs
tcg OBJECT IDENTIFIER ::= {joint-iso-itu-t(2) international-organizations(23) tcg(133)}
tcg-attribute OBJECT IDENTIFIER ::= {tcg 2}
tcg-kp OBJECT IDENTIFIER ::= {tcg 8}
--TCG Attribute OIDs
tcg-at-tpmManufacturer OBJECT IDENTIFIER ::= {tcg-attribute 1}
tcg-at-tpmModel OBJECT IDENTIFIER ::= {tcg-attribute 2}
tcg-at-tpmVersion OBJECT IDENTIFIER ::= {tcg-attribute 3}
tcg-at-tpmSpecification OBJECT IDENTIFIER ::= {tcg-attribute 16}
tcg-at-tpmSecurityAssertions OBJECT IDENTIFIER ::= {tcg-attribute 18}
--TCG Key Purposes OIDs
tcg-kp-EKCertificate OBJECT IDENTIFIER ::= {tcg-kp 1}
-- OIDs not in the module in TCG_IWG_EKCredentialProfile_v2p3_r2_pub but in
-- TCG_IWG_DevID_v1r2_02dec2020 (missing arc names not mentioned in the TCG
-- specs):
tcg-tpm20 OBJECT IDENTIFIER ::= {tcg 1 2} -- this OID is not named in the TCG specs
tcg-on-ekPermIdSha256 OBJECT IDENTIFIER ::= {tcg 12 1}
tcg-cap-verifiedTPMResidency OBJECT IDENTIFIER ::= {tcg 11 1 1} -- policy OID
tcg-cap-verifiedTPMFixed OBJECT IDENTIFIER ::= {tcg 11 1 2} -- policy OID
tcg-cap-verifiedTPMRestricted OBJECT IDENTIFIER ::= {tcg 11 1 3} -- policy OID
EKGenerationType ::= ENUMERATED {
internal (0),
injected (1),
internalRevocable(2),
injectedRevocable(3)
}
EKGenerationLocation ::= ENUMERATED {
tpmManufacturer (0),
platformManufacturer (1),
ekCertSigner (2)
}
EKCertificateGenerationLocation ::= EKGenerationLocation -- XXX
EvaluationAssuranceLevel ::= ENUMERATED {
ealevell (1),
ealevel2 (2),
ealevel3 (3),
ealevel4 (4),
ealevel5 (5),
ealevel6 (6),
ealevel7 (7)
}
SecurityLevel ::= ENUMERATED {
sllevel1 (1),
sllevel2 (2),
sllevel3 (3),
sllevel4 (4)
}
StrengthOfFunction ::= ENUMERATED {
basic (0),
medium (1),
high (2)
}
URIReference ::= SEQUENCE {
uniformResourceIdentifier IA5String, -- (SIZE (1..URIMAX))
hashAlgorithm AlgorithmIdentifier OPTIONAL,
hashValue BIT STRING OPTIONAL
}
EvaluationStatus ::= ENUMERATED {
designedToMeet (0),
evaluationInProgress (1),
evaluationCompleted (2)
}
--tcg specification attributes for tpm
-- tPMSpecification ATTRIBUTE ::= {WITH SYNTAX TPMSpecification ID tcg-at-tpmSpecification }
TPMSpecification ::= SEQUENCE {
family UTF8String, -- (SIZE (1..STRMAX))
level INTEGER,
revision INTEGER,
...
}
--manufacturer implementation model and version attributes
-- TPMManufacturer ATTRIBUTE ::= {WITH SYNTAX UTF8String (SIZE (1..STRMAX)) ID tcg-at-tpmManufacturer }
-- TPMModel ATTRIBUTE ::= {WITH SYNTAX UTF8String (SIZE (1..STRMAX)) ID tcg-at-tpmModel }
-- TPMVersion ATTRIBUTE ::= {WITH SYNTAX UTF8String (SIZE (1..STRMAX)) ID tcg-at-tpmVersion }
--common criteria evaluation
CommonCriteriaMeasures ::= SEQUENCE {
version IA5String, -- (SIZE (1..STRMAX)) “2.2” or “3.1”;future syntax defined by CC
assurancelevel EvaluationAssuranceLevel,
evaluationStatus EvaluationStatus,
plus BOOLEAN DEFAULT FALSE,
strengthOfFunction [0] IMPLICIT StrengthOfFunction OPTIONAL,
profileOid [1] IMPLICIT OBJECT IDENTIFIER OPTIONAL,
profileUri [2] IMPLICIT URIReference OPTIONAL,
targetOid [3] IMPLICIT OBJECT IDENTIFIER OPTIONAL,
targetUri [4] IMPLICIT URIReference OPTIONAL,
...
}
--fips evaluation
FIPSLevel ::= SEQUENCE {
version IA5String, -- (SIZE (1..STRMAX)) “140-1” or “140-2”
level SecurityLevel,
plus BOOLEAN DEFAULT FALSE,
...
}
--tpm security assertions
TPMVersion ::= INTEGER { tpm-v1(0) }
--tPMSecurityAssertions ATTRIBUTE ::= {WITH SYNTAX TPMSecurityAssertions ID tcg—at-tpmSecurityAssertions}
TPMSecurityAssertions ::= SEQUENCE {
version TPMVersion DEFAULT 0, -- v1
fieldUpgradable BOOLEAN DEFAULT FALSE,
ekGenerationType [0] IMPLICIT EKGenerationType OPTIONAL,
ekGenerationLocation [1] IMPLICIT EKGenerationLocation OPTIONAL,
ekCertificateGenerationLocation [2] IMPLICIT EKCertificateGenerationLocation OPTIONAL,
ccInfo [3] IMPLICIT CommonCriteriaMeasures OPTIONAL,
fipsLevel [4] IMPLICIT FIPSLevel OPTIONAL,
iso9000Certified [5] IMPLICIT BOOLEAN DEFAULT FALSE,
iso9000Uri IA5String OPTIONAL, -- (SIZE (1..URIMAX))
...
}
END

File diff suppressed because it is too large Load Diff

View File

@@ -4,7 +4,7 @@ TEST DEFINITIONS ::=
BEGIN
IMPORTS heim_any FROM heim;
IMPORTS HEIM_ANY FROM heim;
-- Check that we handle out of order definitions.
-- The compiler should emit the definition of TESTOutOfOrderBar before that of
@@ -103,7 +103,7 @@ TESTAllocInner ::= SEQUENCE {
TESTAlloc ::= SEQUENCE {
tagless TESTAllocInner OPTIONAL,
three [1] INTEGER (-2147483648..2147483647),
tagless2 heim_any OPTIONAL
tagless2 HEIM_ANY OPTIONAL
}
TESTOptional ::= SEQUENCE {
@@ -117,22 +117,22 @@ TESTENCODEDBY ::= OCTET STRING ( ENCODED BY
{ joint-iso-itu-t(2) asn(1) ber-derived(2) distinguished-encoding(1) }
)
TESTDer OBJECT IDENTIFIER ::= {
testDer OBJECT IDENTIFIER ::= {
joint-iso-itu-t(2) asn(1) ber-derived(2) distinguished-encoding(1)
}
TESTCONTAININGENCODEDBY ::= OCTET STRING ( CONTAINING INTEGER ENCODED BY
testContainingEncodedBy ::= OCTET STRING ( CONTAINING INTEGER ENCODED BY
{ joint-iso-itu-t(2) asn(1) ber-derived(2) distinguished-encoding(1) }
)
TESTCONTAININGENCODEDBY2 ::= OCTET STRING (
CONTAINING INTEGER ENCODED BY TESTDer
testContainingEncodedBy2 ::= OCTET STRING (
CONTAINING INTEGER ENCODED BY testDer
)
TESTValue1 INTEGER ::= 1
testValue1 INTEGER ::= 1
TESTUSERCONSTRAINED ::= OCTET STRING (CONSTRAINED BY { -- meh -- })
testUserConstrained ::= OCTET STRING (CONSTRAINED BY { -- meh -- })
-- TESTUSERCONSTRAINED2 ::= OCTET STRING (CONSTRAINED BY { TESTInteger })
-- TESTUSERCONSTRAINED3 ::= OCTET STRING (CONSTRAINED BY { INTEGER })
-- TESTUSERCONSTRAINED4 ::= OCTET STRING (CONSTRAINED BY { INTEGER : 1 })
@@ -250,4 +250,40 @@ TESTLargeBitString ::= BIT STRING {
TESTMechType::= OBJECT IDENTIFIER
TESTMechTypeList ::= SEQUENCE OF TESTMechType
-- IOS stuff
_EXTENSION ::= CLASS {
&id OBJECT IDENTIFIER UNIQUE,
&ExtnType,
&Critical BOOLEAN DEFAULT FALSE
}
TESTExtension{_EXTENSION:ExtensionSet} ::= SEQUENCE {
extnID _EXTENSION.&id({ExtensionSet}),
critical BOOLEAN
-- (EXTENSION.&Critical({ExtensionSet}{@extnID}))
DEFAULT FALSE,
extnValue OCTET STRING (CONTAINING
_EXTENSION.&ExtnType({ExtensionSet}{@extnID}))
}
id-test-default OBJECT IDENTIFIER ::= { 1 2 3 4 }
testext-TESTDefault _EXTENSION ::= {
&id id-test-default,
&Critical FALSE,
&ExtnType TESTDefault
}
-- And Here's an object set for the EXTENSION CLASS collecting a bunch of
-- related extensions (here they are the extensions that certificates can
-- carry in their extensions member):
TestExtensions _EXTENSION ::= { testext-TESTDefault }
TESTExtension ::= TESTExtension { TestExtensions }
TESTExtensible ::= SEQUENCE {
version INTEGER,
extensions SEQUENCE OF TESTExtension
}
END

View File

@@ -2,11 +2,11 @@
GSS-API DEFINITIONS ::= BEGIN
IMPORTS heim_any_set FROM heim;
IMPORTS HEIM_ANY_SET FROM heim;
GSSAPIContextToken ::= [APPLICATION 0] IMPLICIT SEQUENCE {
thisMech OBJECT IDENTIFIER,
innerContextToken heim_any_set
innerContextToken HEIM_ANY_SET
}
END
END

View File

@@ -38,9 +38,9 @@ gen_files_hdb = \
asn1_HDB_EntryOrAlias.x \
asn1_KeyRotation.x \
asn1_KeyRotationFlags.x \
asn1_hdb_entry.x \
asn1_hdb_entry_alias.x \
asn1_hdb_keyset.x \
asn1_HDB_entry.x \
asn1_HDB_entry_alias.x \
asn1_HDB_keyset.x \
asn1_Keys.x
CLEANFILES = $(BUILT_SOURCES) $(gen_files_hdb) \

View File

@@ -65,7 +65,7 @@ hdb_entry2value(krb5_context context, const hdb_entry *ent, krb5_data *value)
size_t len = 0;
int ret;
ASN1_MALLOC_ENCODE(hdb_entry, value->data, value->length, ent, &len, ret);
ASN1_MALLOC_ENCODE(HDB_entry, value->data, value->length, ent, &len, ret);
if (ret == 0 && value->length != len)
krb5_abortx(context, "internal asn.1 encoder error");
return ret;
@@ -74,7 +74,7 @@ hdb_entry2value(krb5_context context, const hdb_entry *ent, krb5_data *value)
int
hdb_value2entry(krb5_context context, krb5_data *value, hdb_entry *ent)
{
return decode_hdb_entry(value->data, value->length, ent, NULL);
return decode_HDB_entry(value->data, value->length, ent, NULL);
}
int
@@ -85,7 +85,7 @@ hdb_entry_alias2value(krb5_context context,
size_t len = 0;
int ret;
ASN1_MALLOC_ENCODE(hdb_entry_alias, value->data, value->length,
ASN1_MALLOC_ENCODE(HDB_entry_alias, value->data, value->length,
alias, &len, ret);
if (ret == 0 && value->length != len)
krb5_abortx(context, "internal asn.1 encoder error");
@@ -96,7 +96,7 @@ int
hdb_value2entry_alias(krb5_context context, krb5_data *value,
hdb_entry_alias *ent)
{
return decode_hdb_entry_alias(value->data, value->length, ent, NULL);
return decode_HDB_entry_alias(value->data, value->length, ent, NULL);
}
/*
@@ -205,7 +205,7 @@ fetch_entry_or_alias(krb5_context context,
(flags & (HDB_F_CANON|HDB_F_GET_ANY)) == 0) {
/* `principal' was alias but canon not req'd */
free_hdb_entry(&entry->entry);
free_HDB_entry(&entry->entry);
ret = HDB_ERR_NOENTRY;
}
@@ -300,7 +300,7 @@ hdb_remove_aliases(krb5_context context, HDB *db, krb5_data *key)
code = hdb_entry_get_aliases(&oldentry, &aliases);
if (code || aliases == NULL) {
free_hdb_entry(&oldentry);
free_HDB_entry(&oldentry);
return code;
}
for (i = 0; i < aliases->aliases.len; i++) {
@@ -312,11 +312,11 @@ hdb_remove_aliases(krb5_context context, HDB *db, krb5_data *key)
krb5_data_free(&akey);
}
if (code) {
free_hdb_entry(&oldentry);
free_HDB_entry(&oldentry);
return code;
}
}
free_hdb_entry(&oldentry);
free_HDB_entry(&oldentry);
return 0;
}
@@ -790,7 +790,7 @@ derive_keys_for_kr(krb5_context context,
if (ret == 0)
ret = hdb_install_keyset(context, &h->entry, is_current_keyset, &dks);
free_hdb_keyset(&dks);
free_HDB_keyset(&dks);
return ret;
}
@@ -1468,3 +1468,111 @@ hdb_fetch_kvno(krb5_context context,
krb5_set_error_message(context, ret, "no such entry found in hdb");
return ret;
}
size_t ASN1CALL
length_hdb_keyset(HDB_keyset *data)
{
return length_HDB_keyset(data);
}
size_t ASN1CALL
length_hdb_entry(HDB_entry *data)
{
return length_HDB_entry(data);
}
size_t ASN1CALL
length_hdb_entry_alias(HDB_entry_alias *data)
{
return length_HDB_entry_alias(data);
}
void ASN1CALL
free_hdb_keyset(HDB_keyset *data)
{
free_HDB_keyset(data);
}
void ASN1CALL
free_hdb_entry(HDB_entry *data)
{
free_HDB_entry(data);
}
void ASN1CALL
free_hdb_entry_alias(HDB_entry_alias *data)
{
free_HDB_entry_alias(data);
}
size_t ASN1CALL
copy_hdb_keyset(const HDB_keyset *from, HDB_keyset *to)
{
return copy_HDB_keyset(from, to);
}
size_t ASN1CALL
copy_hdb_entry(const HDB_entry *from, HDB_entry *to)
{
return copy_HDB_entry(from, to);
}
size_t ASN1CALL
copy_hdb_entry_alias(const HDB_entry_alias *from, HDB_entry_alias *to)
{
return copy_HDB_entry_alias(from, to);
}
int ASN1CALL
decode_hdb_keyset(const unsigned char *p,
size_t len,
HDB_keyset *data,
size_t *size)
{
return decode_HDB_keyset(p, len, data, size);
}
int ASN1CALL
decode_hdb_entry(const unsigned char *p,
size_t len,
HDB_entry *data,
size_t *size)
{
return decode_HDB_entry(p, len, data, size);
}
int ASN1CALL
decode_hdb_entry_alias(const unsigned char *p,
size_t len,
HDB_entry_alias *data,
size_t *size)
{
return decode_HDB_entry_alias(p, len, data, size);
}
int ASN1CALL
encode_hdb_keyset(unsigned char *p,
size_t len,
const HDB_keyset *data,
size_t *size)
{
return encode_HDB_keyset(p, len, data, size);
}
int ASN1CALL
encode_hdb_entry(unsigned char *p,
size_t len,
const HDB_entry *data,
size_t *size)
{
return encode_HDB_entry(p, len, data, size);
}
int ASN1CALL
encode_hdb_entry_alias(unsigned char *p,
size_t len,
const HDB_entry_alias *data,
size_t *size)
{
return encode_HDB_entry_alias(p, len, data, size);
}

View File

@@ -163,7 +163,7 @@ hkt_fetch_kvno(krb5_context context, HDB * db, krb5_const_principal principal,
out:
if (ret) {
free_hdb_entry(&entry->entry);
free_HDB_entry(&entry->entry);
memset(&entry->entry, 0, sizeof(entry->entry));
}
krb5_kt_free_entry(context, &ktentry);

View File

@@ -662,7 +662,7 @@ out:
if (ret == HEIM_ERR_EOF)
/* Better error code than "end of file" */
ret = HEIM_ERR_BAD_HDBENT_ENCODING;
free_hdb_entry(entry);
free_HDB_entry(entry);
free_Key(&k);
return ret;
}

View File

@@ -99,14 +99,14 @@ HDB-Ext-Aliases ::= SEQUENCE {
Keys ::= SEQUENCE OF Key
hdb_keyset ::= SEQUENCE {
HDB_keyset ::= SEQUENCE {
kvno[0] INTEGER (0..4294967295),
keys[1] Keys,
set-time[2] KerberosTime OPTIONAL, -- time this keyset was created/set
...
}
HDB-Ext-KeySet ::= SEQUENCE OF hdb_keyset
HDB-Ext-KeySet ::= SEQUENCE OF HDB_keyset
--
-- We need a function of current (or given, but it will always be current) time
@@ -218,7 +218,7 @@ HDB-extensions ::= SEQUENCE OF HDB-extension
-- Just for convenience, for encoding this as TL data in lib/kadm5
HDB-EncTypeList ::= SEQUENCE OF INTEGER (0..4294967295)
hdb_entry ::= SEQUENCE {
HDB_entry ::= SEQUENCE {
principal[0] Principal OPTIONAL, -- this is optional only
-- for compatibility with libkrb5
kvno[1] INTEGER (0..4294967295),
@@ -236,13 +236,13 @@ hdb_entry ::= SEQUENCE {
extensions[13] HDB-extensions OPTIONAL
}
hdb_entry_alias ::= [APPLICATION 0] SEQUENCE {
HDB_entry_alias ::= [APPLICATION 0] SEQUENCE {
principal[0] Principal OPTIONAL
}
HDB-EntryOrAlias ::= CHOICE {
entry hdb_entry,
alias hdb_entry_alias
entry HDB_entry,
alias HDB_entry_alias
}
END

View File

@@ -406,7 +406,7 @@ hdb_free_entry(krb5_context context, hdb_entry_ex *ent)
memset (k->key.keyvalue.data, 0, k->key.keyvalue.length);
}
free_hdb_entry(&ent->entry);
free_HDB_entry(&ent->entry);
}
krb5_error_code

View File

@@ -44,6 +44,9 @@
#include <heim_asn1.h>
#include <hdb_asn1.h>
typedef HDB_keyset hdb_keyset;
typedef HDB_entry hdb_entry;
typedef HDB_entry_alias hdb_entry_alias;
struct hdb_dbinfo;

View File

@@ -322,8 +322,8 @@ hdb_add_history_keyset(krb5_context context,
for (i = 0; i < hist_keys->len; i++) {
if (hist_keys->val[i].kvno == ks->kvno) {
/* Replace existing */
free_hdb_keyset(&hist_keys->val[i]);
ret = copy_hdb_keyset(ks, &hist_keys->val[i]);
free_HDB_keyset(&hist_keys->val[i]);
ret = copy_HDB_keyset(ks, &hist_keys->val[i]);
break;
}
}
@@ -422,7 +422,7 @@ hdb_add_history_key(krb5_context context, hdb_entry *entry, krb5_kvno kvno, Key
}
out:
free_hdb_keyset(&keyset);
free_HDB_keyset(&keyset);
free_HDB_extension(&ext);
return ret;
}
@@ -462,7 +462,7 @@ hdb_change_kvno(krb5_context context, krb5_kvno new_kvno, hdb_entry *entry)
for (i = 0; i < hist_keys->len; i++) {
if (hist_keys->val[i].kvno == new_kvno) {
found = 1;
ret = copy_hdb_keyset(&hist_keys->val[i], &keyset);
ret = copy_HDB_keyset(&hist_keys->val[i], &keyset);
if (ret)
goto out;
ret = remove_HDB_Ext_KeySet(hist_keys, i);
@@ -485,7 +485,7 @@ hdb_change_kvno(krb5_context context, krb5_kvno new_kvno, hdb_entry *entry)
memset(&keyset.keys, 0, sizeof (keyset.keys));
out:
free_hdb_keyset(&keyset);
free_HDB_keyset(&keyset);
return ret;
}

View File

@@ -1,5 +1,5 @@
EXPORTS
encode_hdb_keyset
encode_HDB_keyset
_hdb_fetch_kvno
_hdb_remove
_hdb_store
@@ -90,7 +90,7 @@ EXPORTS
hdb_value2entry
hdb_value2entry_alias
hdb_write_master_key
length_hdb_keyset
length_HDB_keyset
initialize_hdb_error_table_r
hdb_kt_ops
@@ -108,7 +108,9 @@ EXPORTS
copy_Event
copy_HDB_EncTypeList
copy_hdb_entry
copy_HDB_entry
copy_hdb_entry_alias
copy_HDB_entry_alias
copy_HDB_EntryOrAlias
copy_HDB_extensions
copy_HDB_Ext_KeyRotation
@@ -117,7 +119,9 @@ EXPORTS
copy_Salt
decode_HDB_EncTypeList
decode_hdb_entry
decode_HDB_entry
decode_hdb_entry_alias
decode_HDB_entry_alias
decode_HDB_EntryOrAlias
decode_HDB_Ext_Aliases
decode_HDB_extension
@@ -127,18 +131,23 @@ EXPORTS
decode_Keys
encode_HDB_EncTypeList
encode_hdb_entry
encode_HDB_entry
encode_hdb_entry_alias
encode_HDB_entry_alias
encode_HDB_EntryOrAlias
encode_HDB_Ext_Aliases
encode_HDB_extension
encode_HDB_Ext_KeyRotation
encode_HDB_Ext_PKINIT_acl
encode_hdb_keyset
encode_Key
encode_Keys
free_Event
free_HDB_EncTypeList
free_hdb_entry
free_HDB_entry
free_hdb_entry_alias
free_HDB_entry_alias
free_HDB_EntryOrAlias
free_HDB_Ext_Aliases
free_HDB_extension
@@ -147,6 +156,7 @@ EXPORTS
free_HDB_Ext_KeySet
free_HDB_Ext_PKINIT_acl
free_hdb_keyset
free_HDB_keyset
free_Key
free_Keys
free_Salt
@@ -156,12 +166,15 @@ EXPORTS
KeyRotationFlags2int
length_HDB_EncTypeList
length_hdb_entry
length_HDB_entry
length_hdb_entry_alias
length_HDB_entry_alias
length_HDB_EntryOrAlias
length_HDB_Ext_Aliases
length_HDB_extension
length_HDB_Ext_KeyRotation
length_HDB_Ext_PKINIT_acl
length_hdb_keyset
length_Key
length_Keys
remove_HDB_Ext_KeyRotation

View File

@@ -101,7 +101,7 @@ threaded_reader(void *d)
//(void) unlink(s->fname);
krb5_err(context, 1, ret, "Could not iterate HDB %s", s->hdb_name);
}
free_hdb_entry(&entr.entry);
free_HDB_entry(&entr.entry);
/* Tell the writer to go ahead and write */
printf("Reader thread iterated one entry; telling writer to write more\n");
@@ -124,7 +124,7 @@ threaded_reader(void *d)
"Could not iterate while writing to HDB %s", s->hdb_name);
}
printf("Reader thread iterated another entry\n");
free_hdb_entry(&entr.entry);
free_HDB_entry(&entr.entry);
if ((ret = dbr->hdb_nextkey(context, dbr, 0, &entr)) == 0) {
//(void) unlink(s->fname);
krb5_warn(context, ret,
@@ -188,7 +188,7 @@ forked_reader(struct tsync *s)
krb5_err(context, 1, ret, "Could not iterate HDB %s", s->hdb_name);
}
printf("Reader process iterated one entry\n");
free_hdb_entry(&entr.entry);
free_HDB_entry(&entr.entry);
/* Tell the writer to go ahead and write */
printf("Reader process iterated one entry; telling writer to write more\n");
@@ -213,7 +213,7 @@ forked_reader(struct tsync *s)
krb5_err(context, 1, ret,
"Could not iterate while writing to HDB %s", s->hdb_name);
}
free_hdb_entry(&entr.entry);
free_HDB_entry(&entr.entry);
printf("Reader process iterated another entry\n");
if ((ret = dbr->hdb_nextkey(context, dbr, 0, &entr)) == 0) {
//(void) unlink(s->fname);
@@ -387,14 +387,14 @@ test_hdb_concurrency(char *name, const char *ext, int threaded)
krb5_err(context, 1, ret,
"Could not store entry for \"foo\" in HDB %s", name);
}
free_hdb_entry(&entw.entry);
free_HDB_entry(&entw.entry);
if ((ret = make_entry(context, &entw, "bar")) ||
(ret = dbw->hdb_store(context, dbw, 0, &entw))) {
(void) unlink(fname_ext);
krb5_err(context, 1, ret,
"Could not store entry for \"foo\" in HDB %s", name);
}
free_hdb_entry(&entw.entry);
free_HDB_entry(&entw.entry);
/* Tell the reader to start reading */
readers_turn(&ts, child, threaded);
@@ -407,7 +407,7 @@ test_hdb_concurrency(char *name, const char *ext, int threaded)
"Could not store entry for \"foobar\" in HDB %s "
"while iterating it", name);
}
free_hdb_entry(&entw.entry);
free_HDB_entry(&entw.entry);
/* Tell the reader to go again */
readers_turn(&ts, child, threaded);

View File

@@ -68,7 +68,7 @@ check_HDB_EntryOrAlias(krb5_context context)
NULL);
if (ret)
krb5_err(context, 1, ret, "krb5_make_principal");
ASN1_MALLOC_ENCODE(hdb_entry_alias, v.data, v.length, &alias, &len, ret);
ASN1_MALLOC_ENCODE(HDB_entry_alias, v.data, v.length, &alias, &len, ret);
if (ret)
krb5_err(context, 1, ret, "encode_HDB_EntryOrAlias");
if (v.length != len)
@@ -79,7 +79,7 @@ check_HDB_EntryOrAlias(krb5_context context)
if (v.length != len)
abort();
free_HDB_EntryOrAlias(&eoa);
free_hdb_entry_alias(&alias);
free_HDB_entry_alias(&alias);
krb5_data_free(&v);
ret = krb5_make_principal(context, &entry.principal, "KTH.SE", "foo",
@@ -88,7 +88,7 @@ check_HDB_EntryOrAlias(krb5_context context)
krb5_err(context, 1, ret, "krb5_make_principal");
entry.kvno = 5;
entry.flags.initial = 1;
ASN1_MALLOC_ENCODE(hdb_entry, v.data, v.length, &entry, &len, ret);
ASN1_MALLOC_ENCODE(HDB_entry, v.data, v.length, &entry, &len, ret);
if (ret)
krb5_err(context, 1, ret, "encode_HDB_EntryOrAlias");
if (v.length != len)
@@ -99,7 +99,7 @@ check_HDB_EntryOrAlias(krb5_context context)
if (v.length != len)
abort();
free_HDB_EntryOrAlias(&eoa);
free_hdb_entry(&entry);
free_HDB_entry(&entry);
krb5_data_free(&v);
}

View File

@@ -104,7 +104,7 @@ main(int argc, char **argv)
krb5_free_principal (context, principal);
ASN1_MALLOC_ENCODE(hdb_keyset, data, length, &keyset, &len, ret);
ASN1_MALLOC_ENCODE(HDB_keyset, data, length, &keyset, &len, ret);
if (ret)
krb5_errx(context, 1, "encode keyset");
if (len != length)

View File

@@ -92,6 +92,7 @@ HEIMDAL_HDB_1.0 {
hdb_value2entry_alias;
hdb_write_master_key;
length_hdb_keyset;
length_HDB_keyset;
hdb_interface_version;
initialize_hdb_error_table_r;
@@ -113,6 +114,8 @@ HEIMDAL_HDB_1.0 {
copy_HDB_EncTypeList;
copy_hdb_entry;
copy_hdb_entry_alias;
copy_HDB_entry;
copy_HDB_entry_alias;
copy_HDB_EntryOrAlias;
copy_HDB_extensions;
copy_HDB_Ext_KeyRotation;
@@ -122,6 +125,8 @@ HEIMDAL_HDB_1.0 {
decode_HDB_EncTypeList;
decode_hdb_entry;
decode_hdb_entry_alias;
decode_HDB_entry;
decode_HDB_entry_alias;
decode_HDB_EntryOrAlias;
decode_HDB_Ext_Aliases;
decode_HDB_extension;
@@ -132,18 +137,23 @@ HEIMDAL_HDB_1.0 {
encode_HDB_EncTypeList;
encode_hdb_entry;
encode_hdb_entry_alias;
encode_HDB_entry;
encode_HDB_entry_alias;
encode_HDB_EntryOrAlias;
encode_HDB_Ext_Aliases;
encode_HDB_extension;
encode_HDB_Ext_KeyRotation;
encode_HDB_Ext_PKINIT_acl;
encode_hdb_keyset;
encode_HDB_keyset;
encode_Key;
encode_Keys;
free_Event;
free_HDB_EncTypeList;
free_hdb_entry;
free_hdb_entry_alias;
free_HDB_entry;
free_HDB_entry_alias;
free_HDB_EntryOrAlias;
free_HDB_Ext_Aliases;
free_HDB_extension;
@@ -152,6 +162,7 @@ HEIMDAL_HDB_1.0 {
free_HDB_Ext_KeySet;
free_HDB_Ext_PKINIT_acl;
free_hdb_keyset;
free_HDB_keyset;
free_Key;
free_Keys;
free_Salt;
@@ -162,6 +173,8 @@ HEIMDAL_HDB_1.0 {
length_HDB_EncTypeList;
length_hdb_entry;
length_hdb_entry_alias;
length_HDB_entry;
length_HDB_entry_alias;
length_HDB_EntryOrAlias;
length_HDB_Ext_Aliases;
length_HDB_extension;

View File

@@ -1284,7 +1284,7 @@ hx509_ca_tbs_add_san_permanentIdentifier(hx509_context context,
_hx509_abort("internal ASN.1 encoder error");
ret = hx509_ca_tbs_add_san_otherName(context, tbs,
&asn1_oid_id_on_permanentIdentifier,
&asn1_oid_id_pkix_on_permanentIdentifier,
&os);
free(os.data);
return ret;
@@ -1595,16 +1595,7 @@ add_extension(hx509_context context,
memset(&ext, 0, sizeof(ext));
if (critical_flag) {
ext.critical = malloc(sizeof(*ext.critical));
if (ext.critical == NULL) {
ret = ENOMEM;
hx509_set_error_string(context, 0, ret, "Out of memory");
goto out;
}
*ext.critical = TRUE;
}
ext.critical = critical_flag;
ret = der_copy_oid(oid, &ext.extnID);
if (ret) {
hx509_set_error_string(context, 0, ret, "Out of memory");
@@ -1975,13 +1966,12 @@ ca_sign(hx509_context context,
/* Add BasicConstraints */
{
BasicConstraints bc;
int aCA = 1;
unsigned int path;
memset(&bc, 0, sizeof(bc));
if (tbs->flags.ca) {
bc.cA = &aCA;
bc.cA = 1;
if (tbs->pathLenConstraint >= 0) {
path = tbs->pathLenConstraint;
bc.pathLenConstraint = &path;

View File

@@ -1060,14 +1060,14 @@ check_basic_constraints(hx509_context context, const Certificate *cert,
return ret;
switch(type) {
case PROXY_CERT:
if (bc.cA != NULL && *bc.cA)
if (bc.cA)
ret = HX509_PARENT_IS_CA;
break;
case EE_CERT:
ret = 0;
break;
case CA_CERT:
if (bc.cA == NULL || !*bc.cA)
if (!bc.cA)
ret = HX509_PARENT_NOT_CA;
else if (bc.pathLenConstraint)
if (depth - 1 > *bc.pathLenConstraint)

View File

@@ -1510,7 +1510,7 @@ hx509_cms_create_signed(hx509_context context,
sigctx.anchors = anchors;
sigctx.pool = pool;
sigctx.sd.version = CMSVersion_v3;
sigctx.sd.version = cMSVersion_v3;
der_copy_oid(eContentType, &sigctx.sd.encapContentInfo.eContentType);

View File

@@ -37,7 +37,6 @@
#define HEIMDAL_HX509_H 1
#include <rfc2459_asn1.h>
#include <rfc4043_asn1.h>
#include <rfc4108_asn1.h>
#include <stdarg.h>
#include <stdio.h>

View File

@@ -59,7 +59,6 @@
#include <krb5-types.h>
#include <rfc2459_asn1.h>
#include <rfc4043_asn1.h>
#include <rfc4108_asn1.h>
#include <cms_asn1.h>
#include <pkcs8_asn1.h>
@@ -69,7 +68,6 @@
#include <pkcs10_asn1.h>
#include <asn1_err.h>
#include <pkinit_asn1.h>
#include <tcg_asn1.h>
#include <der.h>

View File

@@ -1238,7 +1238,7 @@ struct {
{ &asn1_oid_id_pkinit_san,
"KerberosPrincipalName",
_hx509_unparse_KRB5PrincipalName },
{ &asn1_oid_id_on_permanentIdentifier,
{ &asn1_oid_id_pkix_on_permanentIdentifier,
"PermanentIdentifier",
_hx509_unparse_PermanentIdentifier },
{ &asn1_oid_id_on_hardwareModuleName,

View File

@@ -585,21 +585,16 @@ check_basicConstraints(hx509_validate_ctx ctx,
printf("\tlength of der data isn't same as extension\n");
validate_print(ctx, HX509_VALIDATE_F_VERBOSE,
"\tis %sa CA\n", b.cA && *b.cA ? "" : "NOT ");
"\tis %sa CA\n", b.cA ? "" : "NOT ");
if (b.pathLenConstraint)
validate_print(ctx, HX509_VALIDATE_F_VERBOSE,
"\tpathLenConstraint: %d\n", *b.pathLenConstraint);
if (b.cA) {
if (*b.cA) {
if (!e->critical)
validate_print(ctx, HX509_VALIDATE_F_VALIDATE,
"Is a CA and not BasicConstraints CRITICAL\n");
status->isca = 1;
}
else
validate_print(ctx, HX509_VALIDATE_F_VALIDATE,
"cA is FALSE, not allowed to be\n");
if (!e->critical)
validate_print(ctx, HX509_VALIDATE_F_VALIDATE,
"Is a CA and not BasicConstraints CRITICAL\n");
status->isca = 1;
}
free_BasicConstraints(&b);

View File

@@ -530,10 +530,7 @@ get_exts(hx509_context context,
memset(&e, 0, sizeof(e));
/* The critical field needs to be made DEFAULT FALSE... */
if ((e.critical = malloc(sizeof(*e.critical))) == NULL)
ret = ENOMEM;
if (ret == 0)
*e.critical = 1;
e.critical = 1;
if (ret == 0)
ASN1_MALLOC_ENCODE(KeyUsage, e.extnValue.data, e.extnValue.length,
&req->ku, &size, ret);
@@ -547,10 +544,7 @@ get_exts(hx509_context context,
Extension e;
memset(&e, 0, sizeof(e));
if ((e.critical = malloc(sizeof(*e.critical))) == NULL)
ret = ENOMEM;
if (ret == 0)
*e.critical = 1;
e.critical = 1;
if (ret == 0)
ASN1_MALLOC_ENCODE(ExtKeyUsage,
e.extnValue.data, e.extnValue.length,
@@ -570,17 +564,11 @@ get_exts(hx509_context context,
*
* The empty DN check could probably stand to be a function we export.
*/
e.critical = NULL;
e.critical = FALSE;
if (req->name &&
req->name->der_name.element == choice_Name_rdnSequence &&
req->name->der_name.u.rdnSequence.len == 0) {
if ((e.critical = malloc(sizeof(*e.critical))) == NULL)
ret = ENOMEM;
if (ret == 0) {
*e.critical = 1;
}
}
req->name->der_name.u.rdnSequence.len == 0)
e.critical = 1;
if (ret == 0)
ASN1_MALLOC_ENCODE(GeneralNames,
e.extnValue.data, e.extnValue.length,
@@ -1241,7 +1229,7 @@ san_map_type(GeneralName *san)
{ &asn1_oid_id_pkinit_san, HX509_SAN_TYPE_PKINIT },
{ &asn1_oid_id_pkix_on_xmppAddr, HX509_SAN_TYPE_XMPP },
{ &asn1_oid_id_pkinit_ms_san, HX509_SAN_TYPE_MS_UPN },
{ &asn1_oid_id_on_permanentIdentifier, HX509_SAN_TYPE_PERMANENT_ID },
{ &asn1_oid_id_pkix_on_permanentIdentifier, HX509_SAN_TYPE_PERMANENT_ID },
{ &asn1_oid_id_on_hardwareModuleName, HX509_SAN_TYPE_HW_MODULE },
};
size_t i;

View File

@@ -48,6 +48,8 @@
#include <k5e1_err.h>
#include <krb5_asn1.h>
typedef Krb5Int32 krb5int32;
typedef Krb5UInt32 krb5uint32;
/* name confusion with MIT */
#ifndef KRB5KDC_ERR_KEY_EXP

View File

@@ -122,6 +122,8 @@ struct mbuf;
#include <krb5_asn1.h>
typedef Krb5Int32 krb5int32;
typedef Krb5UInt32 krb5uint32;
#include <pkinit_asn1.h>
struct send_to_kdc;

View File

@@ -146,7 +146,7 @@ check_transited(krb5_context context, Ticket *ticket, EncTicketPart *enc)
if(enc->transited.tr_type == 0 && enc->transited.contents.length == 0)
return 0;
if(enc->transited.tr_type != DOMAIN_X500_COMPRESS)
if(enc->transited.tr_type != domain_X500_Compress)
return KRB5KDC_ERR_TRTYPE_NOSUPP;
if(enc->transited.contents.length == 0)