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) AM_CONDITIONAL(OPENLDAP_MODULE, test "$enable_hdb_openldap_module" = yes -a "$with_openldap" = yes)
AC_ARG_ENABLE(asn1-templating, 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])) [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
dnl Optional modules, pk-init, digest, kx509 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); 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); krb5_data_zero(&r->et.transited.contents);
/* The MIT ASN.1 library (obviously) doesn't tell lengths encoded /* 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; size_t i;
switch (tr->tr_type) { switch (tr->tr_type) {
case DOMAIN_X500_COMPRESS: case domain_X500_Compress:
break; break;
case 0: case 0:
/* /*
@@ -744,7 +744,7 @@ fix_transited_encoding(krb5_context context,
} }
et->flags.transited_policy_checked = 1; 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); ret = krb5_domain_x500_encode(realms, num_realms, &et->transited.contents);
if(ret) if(ret)
krb5_warn(context, ret, "Encoding transited encoding"); krb5_warn(context, ret, "Encoding transited encoding");

View File

@@ -89,7 +89,7 @@ encode_ticket(krb5_context context,
krb5_data empty_string; krb5_data empty_string;
krb5_data_zero(&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.transited.contents = empty_string;
} }
et.authtime = cred->times.authtime; et.authtime = cred->times.authtime;

View File

@@ -6,6 +6,8 @@ YFLAGS = -d -t
AM_CPPFLAGS += $(ROKEN_RENAME) AM_CPPFLAGS += $(ROKEN_RENAME)
man_MANS = asn1_compile.1
lib_LTLIBRARIES = libasn1.la lib_LTLIBRARIES = libasn1.la
libasn1_la_LDFLAGS = -version-info 8:0:0 libasn1_la_LDFLAGS = -version-info 8:0:0
@@ -23,9 +25,7 @@ libasn1_la_LIBADD = \
BUILT_SOURCES = \ BUILT_SOURCES = \
$(gen_files_rfc2459:.x=.c) \ $(gen_files_rfc2459:.x=.c) \
$(gen_files_rfc4043:.x=.c) \
$(gen_files_rfc4108:.x=.c) \ $(gen_files_rfc4108:.x=.c) \
$(gen_files_tcg:.x=.c) \
$(gen_files_cms:.x=.c) \ $(gen_files_cms:.x=.c) \
$(gen_files_krb5:.x=.c) \ $(gen_files_krb5:.x=.c) \
$(gen_files_ocsp:.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_cms = asn1_cms_asn1.x
gen_files_crmf = asn1_crmf_asn1.x gen_files_crmf = asn1_crmf_asn1.x
gen_files_rfc2459 = asn1_rfc2459_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_rfc4108 = asn1_rfc4108_asn1.x
gen_files_tcg = asn1_tcg_asn1.x
gen_files_ocsp = asn1_ocsp_asn1.x gen_files_ocsp = asn1_ocsp_asn1.x
gen_files_pkinit = asn1_pkinit_asn1.x gen_files_pkinit = asn1_pkinit_asn1.x
gen_files_pkcs10 = asn1_pkcs10_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 check_template_SOURCES = check-template.c check-common.c check-common.h
nodist_check_template_SOURCES = $(gen_files_test_template:.x=.c) 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 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) nodist_check_gen_template_SOURCES = $(gen_files_test_template:.x=.c)
@@ -154,9 +153,7 @@ check_ber_LDADD = $(check_gen_LDADD)
CLEANFILES = \ CLEANFILES = \
$(BUILT_SOURCES) \ $(BUILT_SOURCES) \
$(gen_files_rfc2459) \ $(gen_files_rfc2459) \
$(gen_files_rfc4043) \
$(gen_files_rfc4108) \ $(gen_files_rfc4108) \
$(gen_files_tcg) \
$(gen_files_cms) \ $(gen_files_cms) \
$(gen_files_krb5) \ $(gen_files_krb5) \
$(gen_files_ocsp) \ $(gen_files_ocsp) \
@@ -174,9 +171,7 @@ CLEANFILES = \
asn1parse.c asn1parse.h lex.c \ asn1parse.c asn1parse.h lex.c \
asn1_err.c asn1_err.h \ asn1_err.c asn1_err.h \
rfc2459_asn1_files rfc2459_asn1*.h* rfc2459_asn1*.x \ 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 \ 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 \ cms_asn1_files cms_asn1*.h* cms_asn1*.x \
crmf_asn1_files crmf_asn1*.h* crmf_asn1*.x \ crmf_asn1_files crmf_asn1*.h* crmf_asn1*.x \
krb5_asn1_files krb5_asn1*.h* krb5_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 += cms_asn1.h
nodist_include_HEADERS += crmf_asn1.h nodist_include_HEADERS += crmf_asn1.h
nodist_include_HEADERS += rfc2459_asn1.h nodist_include_HEADERS += rfc2459_asn1.h
nodist_include_HEADERS += rfc4043_asn1.h
nodist_include_HEADERS += rfc4108_asn1.h nodist_include_HEADERS += rfc4108_asn1.h
nodist_include_HEADERS += tcg_asn1.h
nodist_include_HEADERS += ocsp_asn1.h nodist_include_HEADERS += ocsp_asn1.h
nodist_include_HEADERS += pkcs8_asn1.h nodist_include_HEADERS += pkcs8_asn1.h
nodist_include_HEADERS += pkcs9_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 += cms_asn1-priv.h
priv_headers += crmf_asn1-priv.h priv_headers += crmf_asn1-priv.h
priv_headers += rfc2459_asn1-priv.h priv_headers += rfc2459_asn1-priv.h
priv_headers += rfc4043_asn1-priv.h
priv_headers += rfc4108_asn1-priv.h priv_headers += rfc4108_asn1-priv.h
priv_headers += tcg_asn1-priv.h
priv_headers += ocsp_asn1-priv.h priv_headers += ocsp_asn1-priv.h
priv_headers += pkcs8_asn1-priv.h priv_headers += pkcs8_asn1-priv.h
priv_headers += pkcs9_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_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_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_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_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_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_crmf) crmf_asn1.hx crmf_asn1-priv.hx: crmf_asn1_files
$(gen_files_x690sample) x690sample_asn1.hx x690sample_asn1-priv.hx: x690sample_asn1_files $(gen_files_x690sample) x690sample_asn1.hx x690sample_asn1-priv.hx: x690sample_asn1_files
@@ -270,19 +259,12 @@ else
TEMPLATE_OPTION= TEMPLATE_OPTION=
endif endif
# XXX Currently using the template compiler for rfc2459.asn1 breaks
rfc2459_asn1_files: asn1_compile$(EXEEXT) $(srcdir)/rfc2459.asn1 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) $(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 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) $(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 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) $(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 \ pkcs10.asn1 \
pkinit.asn1 \ pkinit.asn1 \
rfc2459.asn1 \ rfc2459.asn1 \
rfc4043.asn1 \
rfc4108.asn1 \ rfc4108.asn1 \
tcg.asn1 \ tcg.asn1 \
setchgpw2.asn1 \ setchgpw2.asn1 \

View File

@@ -31,7 +31,7 @@
RELDIR=lib\asn1 RELDIR=lib\asn1
intcflags=-I$(SRCDIR) -I$(OBJ) -DROKEN_RENAME intcflags=-I$(SRCDIR) -I$(OBJ) -DROKEN_RENAME -DASN1_IOS_SUPPORTED
!include ../../windows/NTMakefile.w32 !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_rfc2459 = $(OBJ)\asn1_rfc2459_asn1.x
gen_files_rfc4043 = $(OBJ)\asn1_rfc4043_asn1.x
gen_files_rfc4108 = $(OBJ)\asn1_rfc4108_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_ocsp = $(OBJ)\asn1_ocsp_asn1.x
gen_files_pkinit = $(OBJ)\asn1_pkinit_asn1.x gen_files_pkinit = $(OBJ)\asn1_pkinit_asn1.x
@@ -128,11 +124,8 @@ LIBASN1_OBJS= \
$(OBJ)\extra.obj \ $(OBJ)\extra.obj \
$(OBJ)\timegm.obj \ $(OBJ)\timegm.obj \
$(gen_files_rfc2459:.x=.obj) \ $(gen_files_rfc2459:.x=.obj) \
$(gen_files_rfc4043:.x=.obj) \
$(gen_files_rfc4108:.x=.obj) \ $(gen_files_rfc4108:.x=.obj) \
$(gen_files_tcg:.x=.obj) \
$(gen_files_cms:.x=.obj) \ $(gen_files_cms:.x=.obj) \
$(gen_files_crmf:.x=.obj) \
$(gen_files_krb5:.x=.obj) \ $(gen_files_krb5:.x=.obj) \
$(gen_files_ocsp:.x=.obj) \ $(gen_files_ocsp:.x=.obj) \
$(gen_files_pkinit:.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_rfc2459:.x=.c) : $$(@R).x
$(gen_files_rfc4043:.x=.c) : $$(@R).x
$(gen_files_rfc4108:.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_cms:.x=.c) : $$(@R).x
$(gen_files_crmf:.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 $(gen_files_krb5) $(OBJ)\krb5_asn1.hx: $(BINDIR)\asn1_compile.exe krb5.asn1 krb5.opt
cd $(OBJ) cd $(OBJ)
$(BINDIR)\asn1_compile.exe \ $(BINDIR)\asn1_compile.exe \
--template \
--one-code-file \ --one-code-file \
--option-file=$(SRCDIR)\krb5.opt \ --option-file=$(SRCDIR)\krb5.opt \
$(SRCDIR)\krb5.asn1 krb5_asn1 \ $(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 $(gen_files_ocsp) $(OBJ)\ocsp_asn1.hx: $(BINDIR)\asn1_compile.exe ocsp.asn1
cd $(OBJ) cd $(OBJ)
$(BINDIR)\asn1_compile.exe \ $(BINDIR)\asn1_compile.exe \
--template \
--one-code-file \ --one-code-file \
--option-file=$(SRCDIR)\ocsp.opt \ --option-file=$(SRCDIR)\ocsp.opt \
$(SRCDIR)\ocsp.asn1 \ $(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 $(gen_files_pkinit) $(OBJ)\pkinit_asn1.hx: $(BINDIR)\asn1_compile.exe pkinit.asn1
cd $(OBJ) 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) || ($(RM) $(OBJ)\pkinit_asn1.h ; exit /b 1)
cd $(SRCDIR) cd $(SRCDIR)
$(gen_files_pkcs8) $(OBJ)\pkcs8_asn1.hx: $(BINDIR)\asn1_compile.exe pkcs8.asn1 $(gen_files_pkcs8) $(OBJ)\pkcs8_asn1.hx: $(BINDIR)\asn1_compile.exe pkcs8.asn1
cd $(OBJ) 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) || ($(RM) $(OBJ)\pkcs8_asn1.h ; exit /b 1)
cd $(SRCDIR) cd $(SRCDIR)
$(gen_files_pkcs9) $(OBJ)\pkcs9_asn1.hx: $(BINDIR)\asn1_compile.exe pkcs9.asn1 $(gen_files_pkcs9) $(OBJ)\pkcs9_asn1.hx: $(BINDIR)\asn1_compile.exe pkcs9.asn1
cd $(OBJ) 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) || ($(RM) $(OBJ)\pkcs9_asn1.h ; exit /b 1)
cd $(SRCDIR) cd $(SRCDIR)
$(gen_files_pkcs10) $(OBJ)\pkcs10_asn1.hx: $(BINDIR)\asn1_compile.exe pkcs10.asn1 $(gen_files_pkcs10) $(OBJ)\pkcs10_asn1.hx: $(BINDIR)\asn1_compile.exe pkcs10.asn1
cd $(OBJ) cd $(OBJ)
$(BINDIR)\asn1_compile.exe \ $(BINDIR)\asn1_compile.exe \
--template \
--one-code-file \ --one-code-file \
--option-file=$(SRCDIR)\pkcs10.opt \ --option-file=$(SRCDIR)\pkcs10.opt \
$(SRCDIR)\pkcs10.asn1 \ $(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 $(gen_files_pkcs12) $(OBJ)\pkcs12_asn1.hx: $(BINDIR)\asn1_compile.exe pkcs12.asn1
cd $(OBJ) 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) || ($(RM) $(OBJ)\pkcs12_asn1.h ; exit /b 1)
cd $(SRCDIR) cd $(SRCDIR)
$(gen_files_digest) $(OBJ)\digest_asn1.hx: $(BINDIR)\asn1_compile.exe digest.asn1 $(gen_files_digest) $(OBJ)\digest_asn1.hx: $(BINDIR)\asn1_compile.exe digest.asn1
cd $(OBJ) 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) || ($(RM) $(OBJ)\digest_asn1.h ; exit /b 1)
cd $(SRCDIR) cd $(SRCDIR)
$(gen_files_kx509) $(OBJ)\kx509_asn1.hx: $(BINDIR)\asn1_compile.exe kx509.asn1 $(gen_files_kx509) $(OBJ)\kx509_asn1.hx: $(BINDIR)\asn1_compile.exe kx509.asn1
cd $(OBJ) 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) || ($(RM) $(OBJ)\kx509_asn1.h ; exit /b 1)
cd $(SRCDIR) cd $(SRCDIR)
$(gen_files_rfc2459) $(OBJ)\rfc2459_asn1.hx: $(BINDIR)\asn1_compile.exe rfc2459.asn1 $(gen_files_rfc2459) $(OBJ)\rfc2459_asn1.hx: $(BINDIR)\asn1_compile.exe rfc2459.asn1
cd $(OBJ) cd $(OBJ)
$(BINDIR)\asn1_compile.exe \ $(BINDIR)\asn1_compile.exe \
--template \
--one-code-file \ --one-code-file \
--option-file=$(SRCDIR)\rfc2459.opt \ --option-file=$(SRCDIR)\rfc2459.opt \
$(SRCDIR)\rfc2459.asn1 rfc2459_asn1 \ $(SRCDIR)\rfc2459.asn1 rfc2459_asn1 \
|| ($(RM) $(OBJ)\rfc2459_asn1.h ; exit /b 1) || ($(RM) $(OBJ)\rfc2459_asn1.h ; exit /b 1)
cd $(SRCDIR) 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 $(gen_files_rfc4108) $(OBJ)\rfc4108_asn1.hx: $(BINDIR)\asn1_compile.exe rfc4108.asn1
cd $(OBJ) cd $(OBJ)
$(BINDIR)\asn1_compile.exe \ $(BINDIR)\asn1_compile.exe \
--template \
--one-code-file \ --one-code-file \
$(SRCDIR)\rfc4108.asn1 rfc4108_asn1 \ $(SRCDIR)\rfc4108.asn1 rfc4108_asn1 \
|| ($(RM) $(OBJ)\rfc4108_asn1.h ; exit /b 1) || ($(RM) $(OBJ)\rfc4108_asn1.h ; exit /b 1)
cd $(SRCDIR) 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 $(gen_files_cms) $(OBJ)\cms_asn1.hx: $(BINDIR)\asn1_compile.exe cms.asn1 cms.opt
cd $(OBJ) cd $(OBJ)
$(BINDIR)\asn1_compile.exe \ $(BINDIR)\asn1_compile.exe \
--template \
--one-code-file --option-file=$(SRCDIR)\cms.opt \ --one-code-file --option-file=$(SRCDIR)\cms.opt \
$(SRCDIR)\cms.asn1 cms_asn1 \ $(SRCDIR)\cms.asn1 cms_asn1 \
|| ($(RM) $(OBJ)\cms_asn1.h ; exit /b 1) || ($(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 $(gen_files_crmf) $(OBJ)\crmf_asn1.hx: $(BINDIR)\asn1_compile.exe crmf.asn1 crmf.opt
cd $(OBJ) cd $(OBJ)
$(BINDIR)\asn1_compile.exe \ $(BINDIR)\asn1_compile.exe \
--template \
--one-code-file --option-file=$(SRCDIR)\crmf.opt \ --one-code-file --option-file=$(SRCDIR)\crmf.opt \
$(SRCDIR)\crmf.asn1 crmf_asn1 \ $(SRCDIR)\crmf.asn1 crmf_asn1 \
|| ($(RM) $(OBJ)\crmf_asn1.h ; exit /b 1) || ($(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 $(gen_files_x690sample) $(OBJ)\x690sample_asn1.hx: $(BINDIR)\asn1_compile.exe x690sample.asn1
cd $(OBJ) cd $(OBJ)
$(BINDIR)\asn1_compile.exe \ $(BINDIR)\asn1_compile.exe \
--template \
--one-code-file \ --one-code-file \
$(SRCDIR)\x690sample.asn1 x690sample_asn1 \ $(SRCDIR)\x690sample.asn1 x690sample_asn1 \
|| ($(RM) $(OBJ)\x690sample_asn1.h ; exit /b 1) || ($(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 $(gen_files_test) $(OBJ)\test_asn1.hx: $(BINDIR)\asn1_compile.exe test.asn1
cd $(OBJ) cd $(OBJ)
$(BINDIR)\asn1_compile.exe \ $(BINDIR)\asn1_compile.exe \
--template \
--one-code-file --sequence=TESTSeqOf \ --one-code-file --sequence=TESTSeqOf \
$(SRCDIR)\test.asn1 test_asn1 \ $(SRCDIR)\test.asn1 test_asn1 \
|| ($(RM) $(OBJ)\test_asn1.h ; exit /b 1) || ($(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 $(gen_files_test_template) $(OBJ)\test_template_asn1.hx: $(BINDIR)\asn1_compile.exe test.asn1
cd $(OBJ) cd $(OBJ)
$(BINDIR)\asn1_compile.exe \ $(BINDIR)\asn1_compile.exe \
--template \
--one-code-file --template \ --one-code-file --template \
--sequence=TESTSeqOf \ --sequence=TESTSeqOf \
$(SRCDIR)\test.asn1 test_template_asn1 \ $(SRCDIR)\test.asn1 test_template_asn1 \
@@ -370,9 +353,7 @@ GENINCFILES= \
$(INCDIR)\pkcs10_asn1.h \ $(INCDIR)\pkcs10_asn1.h \
$(INCDIR)\pkinit_asn1.h \ $(INCDIR)\pkinit_asn1.h \
$(INCDIR)\rfc2459_asn1.h \ $(INCDIR)\rfc2459_asn1.h \
$(INCDIR)\rfc4043_asn1.h \
$(INCDIR)\rfc4108_asn1.h \ $(INCDIR)\rfc4108_asn1.h \
$(INCDIR)\tcg_asn1.h \
$(INCDIR)\x690sample_asn1.h \ $(INCDIR)\x690sample_asn1.h \
$(OBJ)\krb5_asn1-priv.h \ $(OBJ)\krb5_asn1-priv.h \
$(OBJ)\ocsp_asn1-priv.h \ $(OBJ)\ocsp_asn1-priv.h \
@@ -380,9 +361,7 @@ GENINCFILES= \
$(OBJ)\cms_asn1-priv.h \ $(OBJ)\cms_asn1-priv.h \
$(OBJ)\crmf_asn1-priv.h \ $(OBJ)\crmf_asn1-priv.h \
$(OBJ)\rfc2459_asn1-priv.h \ $(OBJ)\rfc2459_asn1-priv.h \
$(OBJ)\rfc4043_asn1-priv.h \
$(OBJ)\rfc4108_asn1-priv.h \ $(OBJ)\rfc4108_asn1-priv.h \
$(OBJ)\tcg_asn1-priv.h \
$(OBJ)\x690sample_asn1-priv.h \ $(OBJ)\x690sample_asn1-priv.h \
$(OBJ)\pkcs8_asn1-priv.h \ $(OBJ)\pkcs8_asn1-priv.h \
$(OBJ)\pkcs9_asn1-priv.h \ $(OBJ)\pkcs9_asn1-priv.h \
@@ -437,7 +416,6 @@ clean::
TEST_BINARIES=\ TEST_BINARIES=\
$(OBJ)\check-der.exe \ $(OBJ)\check-der.exe \
$(OBJ)\check-gen.exe \
$(OBJ)\check-gen-template.exe \ $(OBJ)\check-gen-template.exe \
$(OBJ)\check-timegm.exe \ $(OBJ)\check-timegm.exe \
$(OBJ)\check-ber.exe \ $(OBJ)\check-ber.exe \
@@ -448,7 +426,6 @@ test-binaries: $(TEST_BINARIES)
test-run: test-run:
cd $(OBJ) cd $(OBJ)
-check-der.exe -check-der.exe
-check-gen.exe
-check-gen-template.exe -check-gen-template.exe
-check-timegm.exe -check-timegm.exe
-check-ber.exe -check-ber.exe
@@ -470,11 +447,6 @@ $(OBJ)\check-der.exe: $(OBJ)\check-der.obj $(OBJ)\check-common.obj \
$(EXECONLINK) $(EXECONLINK)
$(EXEPREP_NODIST) $(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 \ $(OBJ)\check-gen-template.exe: $(OBJ)\check-gen.obj $(OBJ)\check-common.obj \
$(LIBHEIMDAL) $(LIBROKEN) $(gen_files_test_template:.x=.obj) $(LIBHEIMDAL) $(LIBROKEN) $(gen_files_test_template:.x=.obj)
$(EXECONLINK) $(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 ## Table of Contents
@@ -6,45 +6,62 @@
2. [Typed Holes / Open Types](#typed-holes--open-types) 2. [Typed Holes / Open Types](#typed-holes--open-types)
3. [ASN.1 IOS, Constraint, and Parameterization](#asn1-ios-constraint-and-parameterization) 3. [ASN.1 IOS, Constraint, and Parameterization](#asn1-ios-constraint-and-parameterization)
- [IOS Crash Course](#ios-crash-course) - [IOS Crash Course](#ios-crash-course)
4. [Implementation Thoughts](#implementation-thoughts) 4. [Usage](#Usage)
5. [Moving From C](#moving-from-c) 5. [Limitations](#Limitations)
6. [Implementation Design](#implementation-design)
7. [Moving From C](#moving-from-c)
## Introduction ## 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.681: Information Object specification
- X.682: Constraint specification - X.682: Constraint specification
- X.683: Parameterization of ASN.1 specifications - 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 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 constraints that would otherwise require natural language to express. Give a
compiler more formally-expressed constraints and it can do more labor-saving compiler more formally-expressed constraints and it can do more labor-saving
than it could otherwise. than it could otherwise.
This README will cover some ideas for what this magic will be, and A subset of these three extensions, X.681, X.682, and X.683, can enable some
implementation of it. 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 RFC 6025 does an excellent job of elucidating X.681, which otherwise most
readers unfamiliar with it will no doubt find inscrutable. Hopefully this 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 The magic that we're after is simply the *automatic and recursive handling of
open types by an ASN.1 compiler*. open types by an ASN.1 compiler*.
Combined with future support for the ASN.1 JSON Encoding Rules (JER) [X.697], Combined with eventual support for the ASN.1 JSON Encoding Rules (JER) [X.697],
the automatic handling of open types should allow us to trivially implement a this feature could give us unprecendented visibility into really complex data
command-line tool that can parse any DER or JER (JSON) encoding of any value structures, such as Endorsement Key Certificates (EKcerts) for Trusted Platform
whose type is known and compiled, and which could transcode to the other Module (TPM) applications.
encoding rules. I.e., dump DER to JSON, and parse JSON to output DER.
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 Combined with transcoders for JSON/CBOR and other binary-JSON formats, we could
support those encodings too. support those encodings too.
@@ -113,12 +130,16 @@ has typed holes, see SSHv2.
In ASN.1 these generally look like: In ASN.1 these generally look like:
```ASN.1 ```ASN.1
TypedHole ::= SEQUENCE { typeId INTEGER, hole OCTET STRING } TypedHole ::= SEQUENCE {
typeId INTEGER,
opaque OCTET STRING
}
``` ```
or or
```ASN.1 ```ASN.1
-- Old ASN.1 style
TypedHole ::= SEQUENCE { TypedHole ::= SEQUENCE {
typeId OBJECT IDENTIFIER, typeId OBJECT IDENTIFIER,
opaque ANY DEFINED BY typeID opaque ANY DEFINED BY typeID
@@ -128,6 +149,7 @@ or
or or
```ASN.1 ```ASN.1
-- Old ASN.1 style
TypedHole ::= SEQUENCE { TypedHole ::= SEQUENCE {
typeId OBJECT IDENTIFIER, typeId OBJECT IDENTIFIER,
opaque ANY -- DEFINED BY typeID 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 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 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 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 the same encoding rules, whereas with typed holes the encoded data could be
conceivably be encoded in radically different encoding rules than the structure encoded in radically different encoding rules than the structure containing it
containing it in a typed hole. in a typed hole.
In fact, extensible `CHOICE`s are handled by our compiler as a discriminated 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 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}} 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 ```ASN.1
-- Here we have an individual "object" specifying that the OID -- 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 -- Lastly, we have a Certificate, and the place where the Extensions type's
-- actual parameter is specified. -- actual parameter is specified.
-- --
-- This is where the *rubber meets the road*! -- This is where the rubber meets the road:
Certificate ::= SIGNED{TBSCertificate} 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` 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 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 `CertExtensions` object set appear as the actual value of the `extnID` member
of an `Extension` value, then the `extnValue` member of the same `Extension` 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, value must be an instance of the type associated with that OID. For example,
an `Extension` with `extnID == id-ce-authorityKeyIdentifier` must have an an `Extension` with `extnID` value of `id-ce-authorityKeyIdentifier` must have
`extnValue` of type `AuthorityKeyIdentifier`. an `extnValue` of type `AuthorityKeyIdentifier`.
### IOS Crash Course ### IOS Crash Course
The ASN.1 IOS is... a bit difficult to understand. X.681 has a lot of strange The ASN.1 IOS may be... a bit difficult to understand -- the syntax isn't
terminology, like "variable type value set field". An IOS "class" has fields, pretty. And X.681 has a lot of strange terminology, like "variable type value
and those fields are of kind `[Fixed]Type[Value[Set]]` or `Object[Set]`. set field".
Classes can have "object sets" associated with them, and each object set has An IOS "class" has fields, and those fields are of kind
zero, one, or more "objects". Each object has settings for all required fields `[Fixed]Type[Value[Set]]` or `Object[Set]`. Then there's "objects" and "object
of a class, and possibly also for optional/defaulted fields as well. sets". Hopefully this section will make all of that comprehensible.
IOS object sets really are akin to relational database tables, while objects _Classes_ have fields of various kinds. More on this below.
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).
These relational entities are constant in that they are defined in ASN.1 _Classes_ can also have zero, one, or more _object sets_ associated with them,
modules that are compiled. There is no way to change them at run-time, only and each object set has zero, one, or more _objects_ that are also themselves
query them. They also have no on-the-wire representation. 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 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 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 using the IOS [X.681], constraint specification [X.682], and type
`SEQUENCE` types (well, really, just `SEQUENCE`) so that our ASN.1 compiler can parameterization [X.683]. We can express the following things:
have the metadata it needs in ordr to auto-generate decoding and encoding of
values of open types.
A termnology point: `SET` and `SEQUENCE` types have "members", but classes and - that some _member_ of a `SET` or `SEQUENCE` is of open type
objects have "fields".
Objects of a class have all the required fields of a class and any of the - that some _member_ of a `SET` or `SEQUENCE` identifies a type encoded into
`OPTIONAL` or `DEFAULT` fields of the class. This is very similar to an open type member of the same (or related) `SET` or `SEQUENCE`
`SET`/`SEQUENCE` members, which can be `OPTIONAL` or `DEFAULT`ed.
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 of a `SET` or `SEQUENCE` type are typed, just as in C, C++, Java, etc. for
struct or object types. struct or object types.
There are several kinds of fields of classes. These can be confusing, so it's There are several kinds of fields of classes. These can be confusing, so it is
essential that we explain them by reference to how they relate to the members useful that we explain them by reference to how they relate to the members of
of `SEQUENCE` types constrained by object sets: `SEQUENCE` types constrained by object sets:
- A `type field` of a class is one that specifies a SET or SEQUENCE member of - A `type field` of a class is one that specifies a `SET` or `SEQUENCE` member
unknown (open) type. of unknown (i.e., open) type.
The type of that SET or SEQUENCE member will not be not truly unknown, but The type of that `SET` or `SEQUENCE` member will not be not truly unknown,
determined by some other member of the SET or SEQUENCE, and that will be 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 specified in a "value field" (or "value set" field) an "object" in an
"object set" of that class. "object set" of that class.
This is essentially a "type variable", as is seen in high-level languages This is essentially a "type variable", akin to those seen in high-level
like Haskell. languages like Haskell.
- A `fixed type value field` of a class is one that specifies a SET or - 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 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 - 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 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 - 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 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 define relations between classes, much like `FOREIGN KEY`s in SQL.
These are also known as `link fields`.
- Similarly for `object set field`s. - Similarly for `object set field`s.
As usual for ASN.1, the case of the first letter of a field name is meaningful: 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; - value and object field names start with a lower case letter;
- type, value set, and object set fields start with an upper-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`.
The form of a `fixed type value` field and a `fixed type value set` field is 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. 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 - The `&id` field of `EXTENSION` is a fixed-type value field. It's not a
_set_ field because its identifier (`id`) starts with a lower-case letter. 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` 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 `SEQUENCE` type name identify the actual type of the `extnValue` member of
the same `SEQUENCE` type. the same `SEQUENCE` type.
The `UNIQUE` keyword tells us there can be only one object with any given Note that `UNIQUE` keyword tells us there can be only one object with any
value of this field in any object set of this class. 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 - 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 - 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. 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. 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 - Ignore the `WITH SYNTAX` clause for now. All it does is specify a
user-friendly butimplementor-hostile syntax for specifying objects for this user-friendly but implementor-hostile syntax for specifying objects.
class.
Note that none of the `Extension` extensions in PKIX actually specify Note that none of the `Extension` extensions in PKIX actually specify
`CRITICALITY`/`&Critical`, so... we just don't need fixed-type value set `CRITICALITY`/`&Critical`, so... we just don't need fixed-type value set
@@ -571,7 +620,7 @@ for object nor object set fields.
Because Because
- no objects in object sets of `EXTENSION` in PKIX specify "criticality", - 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 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: we can drop `MATCHING-RULE` and simplify `ATTRIBUTE` and `EXTENSION` as:
```ASN.1 ```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 Still, for Heimdal we won't bother with the full power of X.681/X.682/X.683 for
now. 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 - 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 non-trivial. We can implement just the subset of those three that we need
we need to implement PKIX, just as we already implement just the subset of to implement PKIX, just as we already implement just the subset of X.680
X.680 that we need to implement PKIX and Kerberos. that we need to implement PKIX and Kerberos.
For dealing with PKIX, the bare minimum of IOS classes we should want are: For dealing with PKIX, the bare minimum of IOS classes we should want are:
- `ATTRIBUTE` (used for `DN` attributes in RFC5280) - `ATTRIBUTE` (used for `DN` attributes in RFC5280, specifically for the
- `EXTENSION` (used for certificate extensions in RFC5280) `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`) - `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 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 three is all we need.
to implement other IOS classes from PKIX, such as `DIGEST-ALGORITHM`
_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 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 all the way down and handle DN attributes, extensions, SANs, policy
qualifiers, the works. qualifiers, the works.
- We'll really want to do this mainly for the template compiler and begin - We'll really want to do this mainly for the template compiler and begin
abandoning the original compiler -- maintaining and developing two compiler abandoning the original compiler. The codegen backend should generate the
backends is difficult enough, but the template compiler is superior just on same C types, but no code for automatic, recursive handling of open types.
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 Maintaining two compiler backends is difficult enough; adding complex
in an ASN.1 module (or all modules). 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 - 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 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 encoding/decoding can still work and we can then update Heimdal in-tree
slowly to take advantage of the new magic. 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 ```C
typedef struct Extension { typedef struct Extension {
-- Existing fields: heim_oid extnID;
heim_oid extnID; int critical;
int *critical; heim_octet_string extnValue;
heim_octet_string extnValue; /* NEW: */
-- New, CHOICE-like fields: struct {
enum Extension_iosnum { enum {
Extension_iosnumunknown = 0, /* when the extnID is unrecognized */ choice_Extension_iosnumunknown = 0,
Extension_iosnum_ext_AuthorityKeyIdentifier = 1, choice_Extension_iosnum_id_x509_ce_authorityKeyIdentifier,
Extension_iosnum_ext_ext-SubjectKeyIdentifier = 2, choice_Extension_iosnum_id_x509_ce_subjectKeyIdentifier,
... choice_Extension_iosnum_id_x509_ce_keyUsage,
} _ios_element; choice_Extension_iosnum_id_x509_ce_privateKeyUsagePeriod,
union { choice_Extension_iosnum_id_x509_ce_certificatePolicies,
heim_octet_string *_value; choice_Extension_iosnum_id_x509_ce_policyMappings,
authorityKeyIdentifier AuthorityKeyIdentifier; choice_Extension_iosnum_id_x509_ce_subjectAltName,
subjectKeyIdentifier SubjectKeyIdentifier; choice_Extension_iosnum_id_x509_ce_issuerAltName,
... choice_Extension_iosnum_id_x509_ce_basicConstraints,
} _ios_u; choice_Extension_iosnum_id_x509_ce_nameConstraints,
} Extension; 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 If a caller to `encode_Certificate()` passes a certificate object with
extensions with `_ioselement == Extension_iosnumunknown`, then the encoder extensions with `_ioselement == choice_Extension_iosnumunknown` (or
should use the `extnID` and `extnValue` fields, otherwise it should use the whatever, for each open type), then the encoder should use the `extnID` and
`_ioselement` and `_iosu` fields and ignore the `extnID` and `extnValue` `extnValue` fields, otherwise it should use the new `_ioschoice_extnValue`
fields. 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 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 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 ID enum field, and a decoded hole value union. All other fields will map to
either normal (possibly constrained) members of the SET/SEQUENCE. either normal (possibly constrained) members of the SET/SEQUENCE.
- Type ID values must get mapped to discrete enum values. We'll want type IDs - Type ID values get mapped to discrete enum values. Object sets get sorted
to be sorted, too, so that we can binary search the object set's template by object type IDs, allowing for a binary search when decoding. For
when decoding for extra speed. For encoding we'll want to "switch" on the encoding and other case we directly index the object set by the mapped type
mapped type ID enum, directly indexing the template for the object set. 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 ```C
encode a new template for the combination of object set and typed hole extern const struct asn1_template asn1_CertExtensions[];
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 const struct asn1_template asn1_Extension_tag__22[] = {
template for one particular object in the object set. The template for each /* 0 */ { 0, sizeof(struct Extension), ((void*)5) },
object will identify the type ID and the template for the associated type. /* 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 ## 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;
typedef struct heim_base_data heim_any_set; 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) \ #define ASN1_MALLOC_ENCODE(T, B, BL, S, L, R) \
do { \ do { \

View File

@@ -38,9 +38,55 @@
#ifndef __TEMPLATE_H__ #ifndef __TEMPLATE_H__
#define __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: /* header:
* HF flags if not a BIT STRING type * HF flags if not a BIT STRING type
* HBF flags if a BIT STRING type * HBF flags if a BIT STRING type
*
* ptr is count of elements
* offset is size of struct
*/ */
/* tag: /* tag:
@@ -49,6 +95,9 @@
* 22..23 class * 22..23 class
* 24..27 flags * 24..27 flags
* 28..31 op * 28..31 op
*
* ptr points to template for tagged type
* offset is offset of struct field
*/ */
/* parse: /* parse:
@@ -56,11 +105,55 @@
* 12..23 unused * 12..23 unused
* 24..27 flags * 24..27 flags
* 28..31 op * 28..31 op
*
* ptr is NULL
* offset is ...
*/ */
/* defval: (next template entry is defaulted) /* defval: (next template entry is defaulted)
* *
* DV flags (ptr is or points to defval) * 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) #define A1_OP_MASK (0xf0000000)
@@ -73,6 +166,10 @@
#define A1_OP_BMEMBER (0x70000000) #define A1_OP_BMEMBER (0x70000000)
#define A1_OP_CHOICE (0x80000000) #define A1_OP_CHOICE (0x80000000)
#define A1_OP_DEFVAL (0x90000000) #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_MASK (0x0f000000)
#define A1_FLAG_OPTIONAL (0x01000000) #define A1_FLAG_OPTIONAL (0x01000000)
@@ -105,6 +202,10 @@
#define A1_DV_INTEGER64 0x08 #define A1_DV_INTEGER64 0x08
#define A1_DV_UTF8STRING 0x10 #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 { struct asn1_template {
uint32_t tt; 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; 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 int
main(int argc, char **argv) main(int argc, char **argv)
{ {
@@ -2072,5 +2322,9 @@ main(int argc, char **argv)
DO_ONE(test_default); DO_ONE(test_default);
#if ASN1_IOS_SUPPORTED
DO_ONE(test_ios);
#endif
return ret; return ret;
} }

View File

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

View File

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

View File

@@ -66,7 +66,7 @@ static const char *tag_names[] = {
NULL, /* 9 */ NULL, /* 9 */
"Enumerated", /* 10 */ "Enumerated", /* 10 */
NULL, /* 11 */ NULL, /* 11 */
NULL, /* 12 */ "UTF8String", /* 12 */
NULL, /* 13 */ NULL, /* 13 */
NULL, /* 14 */ NULL, /* 14 */
NULL, /* 15 */ 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); 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 int
encode_heim_any_set(unsigned char *p, size_t len, encode_heim_any_set(unsigned char *p, size_t len,
const heim_any_set *data, size_t *size) const heim_any_set *data, size_t *size)
@@ -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); 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"); "} heim_bit_string;\n\n");
fprintf (headerfile, fprintf (headerfile,
"typedef struct heim_base_data heim_any;\n" "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" fputs("#define ASN1_MALLOC_ENCODE(T, B, BL, S, L, R) \\\n"
" do { \\\n" " do { \\\n"
" (BL) = length_##T((S)); \\\n" " (BL) = length_##T((S)); \\\n"
@@ -643,7 +645,12 @@ define_asn1 (int level, Type *t)
{ {
switch (t->type) { switch (t->type) {
case TType: 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; break;
case TInteger: case TInteger:
if(t->members == NULL) { if(t->members == NULL) {
@@ -810,8 +817,215 @@ getnewbasename(char **newbasename, int typedefp, const char *basename, const cha
err(1, "malloc"); 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 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 = NULL;
const char *label_prefix_sep = 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) { switch (t->type) {
case TType: case TType:
space(level); 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; break;
case TInteger: case TInteger:
if (t->symbol && t->symbol->emitted_definition) 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) { while (pos < m->val) {
if (asprintf (&n, "_unused%d:1", pos) < 0 || n == NULL) if (asprintf (&n, "_unused%d:1", pos) < 0 || n == NULL)
err(1, "malloc"); err(1, "malloc");
define_type (level + 1, n, newbasename, &i, FALSE, FALSE); define_type(level + 1, n, newbasename, NULL, &i, FALSE, FALSE);
free(n); free(n);
pos++; pos++;
} }
@@ -923,7 +1142,7 @@ define_type (int level, const char *name, const char *basename, Type *t, int typ
n = NULL; n = NULL;
if (asprintf (&n, "%s:1", m->gen_name) < 0 || n == NULL) if (asprintf (&n, "%s:1", m->gen_name) < 0 || n == NULL)
errx(1, "malloc"); errx(1, "malloc");
define_type (level + 1, n, newbasename, &i, FALSE, FALSE); define_type(level + 1, n, newbasename, NULL, &i, FALSE, FALSE);
free (n); free (n);
n = NULL; n = NULL;
pos++; pos++;
@@ -938,7 +1157,7 @@ define_type (int level, const char *name, const char *basename, Type *t, int typ
char *n = NULL; char *n = NULL;
if (asprintf (&n, "_unused%d:1", pos) < 0 || n == NULL) if (asprintf (&n, "_unused%d:1", pos) < 0 || n == NULL)
errx(1, "malloc"); errx(1, "malloc");
define_type (level + 1, n, newbasename, &i, FALSE, FALSE); define_type(level + 1, n, newbasename, NULL, &i, FALSE, FALSE);
free(n); free(n);
pos++; pos++;
} }
@@ -989,13 +1208,15 @@ define_type (int level, const char *name, const char *basename, Type *t, int typ
} else if (m->optional) { } else if (m->optional) {
char *n = NULL; 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"); 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); free (n);
} else } 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); space(level);
fprintf (headerfile, "} %s;\n", name); fprintf (headerfile, "} %s;\n", name);
break; break;
@@ -1013,8 +1234,8 @@ define_type (int level, const char *name, const char *basename, Type *t, int typ
space(level); space(level);
fprintf (headerfile, "struct %s {\n", newbasename); fprintf (headerfile, "struct %s {\n", newbasename);
define_type (level + 1, "len", newbasename, &i, FALSE, FALSE); define_type(level + 1, "len", newbasename, t, &i, FALSE, FALSE);
define_type (level + 1, "*val", newbasename, t->subtype, FALSE, FALSE); define_type(level + 1, "*val", newbasename, t, t->subtype, FALSE, FALSE);
space(level); space(level);
fprintf (headerfile, "} %s;\n", name); fprintf (headerfile, "} %s;\n", name);
break; 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); fprintf (headerfile, "heim_general_string %s;\n", name);
break; break;
case TTag: case TTag:
define_type (level, name, basename, t->subtype, typedefp, preservep); define_type(level, name, basename, t, t->subtype, typedefp, preservep);
break; break;
case TChoice: { case TChoice: {
int first = 1; 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) if (asprintf (&n, "*%s", m->gen_name) < 0 || n == NULL)
errx(1, "malloc"); 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); free (n);
} else } 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); space(level + 1);
fprintf (headerfile, "} u;\n"); fprintf (headerfile, "} u;\n");
@@ -1140,7 +1361,7 @@ declare_type(const Symbol *s, Type *t, int typedefp)
switch (t->type) { switch (t->type) {
case TType: 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) if (template_flag)
generate_template_type_forward(s->gen_name); generate_template_type_forward(s->gen_name);
emitted_declaration(s); emitted_declaration(s);
@@ -1162,7 +1383,7 @@ declare_type(const Symbol *s, Type *t, int typedefp)
case TVisibleString: case TVisibleString:
case TOID : case TOID :
case TNull: 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) if (template_flag)
generate_template_type_forward(s->gen_name); generate_template_type_forward(s->gen_name);
emitted_declaration(s); emitted_declaration(s);
@@ -1295,10 +1516,12 @@ generate_subtypes_header(const Symbol *s)
switch (t->type) { switch (t->type) {
default: return; default: return;
case TType: case TType: {
if (t->symbol && (s = getsym(t->symbol->name))) Symbol *s2;
generate_type_header(s); if (t->symbol && (s2 = getsym(t->symbol->name)) != s)
generate_type_header(s2);
return; return;
}
case TSet: case TSet:
case TSequence: case TSequence:
case TChoice: case TChoice:
@@ -1342,10 +1565,14 @@ generate_type_header (const Symbol *s)
* needed in stripped objects. * needed in stripped objects.
*/ */
if (!s->emitted_tag_enums) { if (!s->emitted_tag_enums) {
while (t->type == TType && s->type->symbol && s->type->symbol->type) while (t->type == TType && s->type->symbol && s->type->symbol->type) {
t = 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 * This type is ultimately an alias of an imported type, so we don't
* know its outermost tag here. * know its outermost tag here.
@@ -1375,13 +1602,10 @@ generate_type_header (const Symbol *s)
return; return;
fprintf(headerfile, "typedef "); 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); preserve_type(s->name) ? TRUE : FALSE);
fprintf(headerfile, "\n"); fprintf(headerfile, "\n");
if (template_flag)
generate_template_type_forward(s->gen_name);
emitted_definition(s); emitted_definition(s);
} }
@@ -1390,6 +1614,8 @@ generate_type_header_forwards(const Symbol *s)
{ {
declare_type(s, s->type, TRUE); declare_type(s, s->type, TRUE);
fprintf(headerfile, "\n"); fprintf(headerfile, "\n");
if (template_flag)
generate_template_type_forward(s->gen_name);
} }
void 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 == TSequence ||
t->subtype->type == TSet)) t->subtype->type == TSet))
replace_tag = 1; 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; replace_tag = 1;
} else if (t->tag.tagenv == TE_IMPLICIT && prim && t->subtype->symbol) } else if (t->tag.tagenv == TE_IMPLICIT && prim && t->subtype->symbol)
replace_tag = 1; replace_tag = 1;

View File

@@ -103,17 +103,9 @@ generate_units (const Type *t, const char *gen_name)
{ {
Member *m; Member *m;
if (template_flag) { fprintf (headerfile,
fprintf (headerfile, "const struct units * asn1_%s_units(void);\n",
"extern const struct units *asn1_%s_table_units;\n", gen_name);
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 (get_code_file(), fprintf (get_code_file(),
"static struct units %s_units[] = {\n", "static struct units %s_units[] = {\n",
@@ -130,16 +122,11 @@ generate_units (const Type *t, const char *gen_name)
"\t{NULL,\t0}\n" "\t{NULL,\t0}\n"
"};\n\n"); "};\n\n");
if (template_flag) fprintf (get_code_file(),
fprintf (get_code_file(), "const struct units * asn1_%s_units(void){\n"
"const struct units * asn1_%s_table_units = %s_units;\n", "return %s_units;\n"
gen_name, gen_name); "}\n\n",
else 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_compare_defval(const char *, struct value *);
void gen_assign_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 *); void init_generate (const char *, const char *);
const char *get_filename (void); const char *get_filename (void);
@@ -144,9 +145,15 @@ int seq_type(const char *);
void generate_header_of_codefile(const char *); void generate_header_of_codefile(const char *);
void close_codefile(void); void close_codefile(void);
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 *); int is_template_compat (const Symbol *);
void generate_template(const Symbol *); void generate_template(const Symbol *);
void generate_template_type_forward(const char *); void generate_template_type_forward(const char *);
void generate_template_objectset_forwards(const Symbol *);
void gen_template_import(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 *, ...) static void add_line_pointer(struct templatehead *, const char *, const char *, const char *, ...)
__attribute__ ((__format__ (__printf__, 4, 5))); __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); 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 * static struct template *
@@ -442,6 +444,10 @@ add_line(struct templatehead *t, const char *fmt, ...)
return q; 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 static void
add_line_pointer(struct templatehead *t, add_line_pointer(struct templatehead *t,
const char *ptr, const char *ptr,
@@ -464,6 +470,28 @@ add_line_pointer(struct templatehead *t,
q->ptr = strdup(ptr); 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 static int
use_extern(const Symbol *s) 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 static void
template_members(struct templatehead *temp, template_members(struct templatehead *temp,
const char *basetype, const char *basetype,
@@ -742,7 +993,18 @@ template_members(struct templatehead *temp,
break; break;
} }
case TSet: { case TSet: {
Member *opentypemember = NULL;
Member *typeidmember = NULL;
Field *opentypefield = NULL;
Field *typeidfield = NULL;
Member *m; 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); fprintf(get_code_file(), "/* tset: members isstruct: %d */\n", isstruct);
@@ -752,6 +1014,9 @@ template_members(struct templatehead *temp,
if (m->ellipsis) if (m->ellipsis)
continue; continue;
if (typeidmember == m) typeididx = i;
if (opentypemember == m) opentypeidx = i;
if (name) { if (name) {
if (asprintf(&newbasename, "%s_%s", basetype, name) < 0) if (asprintf(&newbasename, "%s_%s", basetype, name) < 0)
errx(1, "malloc"); 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); template_members(temp, newbasename, m->gen_name, m->type, m->optional, m->defval ? 1 : 0, 0, isstruct, 1);
free(newbasename); 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; break;
} }
case TSequence: { case TSequence: {
Member *opentypemember = NULL;
Member *typeidmember = NULL;
Field *opentypefield = NULL;
Field *typeidfield = NULL;
Member *m; 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); fprintf(get_code_file(), "/* tsequence: members isstruct: %d */\n", isstruct);
@@ -781,6 +1062,9 @@ template_members(struct templatehead *temp,
if (m->ellipsis) if (m->ellipsis)
continue; continue;
if (typeidmember == m) typeididx = i;
if (opentypemember == m) opentypeidx = i;
if (name) { if (name) {
if (asprintf(&newbasename, "%s_%s", basetype, name) < 0) if (asprintf(&newbasename, "%s_%s", basetype, name) < 0)
errx(1, "malloc"); 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); template_members(temp, newbasename, m->gen_name, m->type, m->optional, m->defval ? 1 : 0, 0, isstruct, 1);
free(newbasename); 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; break;
} }
case TTag: { 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); 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 static void
generate_template_type(const char *varname, generate_template_type(const char *varname,
const char **dupname, 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 copy_heim_any_set(const heim_any_set *, heim_any_set *);
int heim_any_cmp(const heim_any_set *, const 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__ */ #endif /* __HEIM_ANY_H__ */

View File

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

View File

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

View File

@@ -123,7 +123,8 @@ struct getargs args[] = {
"the ASN.1 module instead of topologically sorting types. This " "the ASN.1 module instead of topologically sorting types. This "
"is useful for comparing output to earlier compiler versions.", "is useful for comparing output to earlier compiler versions.",
NULL }, 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, { "type-file", 0, arg_string, &type_file_string,
"Name of a C header file to generate includes of for base types", "Name of a C header file to generate includes of for base types",
"C-HEADER-FILE" }, "C-HEADER-FILE" },

View File

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

View File

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

View File

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

View File

@@ -9,7 +9,13 @@
RFC2459 DEFINITIONS ::= BEGIN 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 { Version ::= INTEGER {
rfc3280_version_1(0), rfc3280_version_1(0),
@@ -169,6 +175,10 @@ id-Userid OBJECT IDENTIFIER ::=
id-domainComponent OBJECT IDENTIFIER ::= id-domainComponent OBJECT IDENTIFIER ::=
{ 0 9 2342 19200300 100 1 25 } { 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 -- rfc3280
@@ -176,12 +186,12 @@ id-x509-ce OBJECT IDENTIFIER ::= {joint-iso-ccitt(2) ds(5) 29}
AlgorithmIdentifier ::= SEQUENCE { AlgorithmIdentifier ::= SEQUENCE {
algorithm OBJECT IDENTIFIER, algorithm OBJECT IDENTIFIER,
parameters heim_any OPTIONAL parameters HEIM_ANY OPTIONAL
} }
AttributeType ::= OBJECT IDENTIFIER AttributeType ::= OBJECT IDENTIFIER
AttributeValue ::= heim_any AttributeValue ::= HEIM_ANY
DirectoryString ::= CHOICE { DirectoryString ::= CHOICE {
ia5String IA5String, ia5String IA5String,
@@ -204,7 +214,18 @@ AttributeTypeAndValue ::= SEQUENCE {
value DirectoryString 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 RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
@@ -231,10 +252,48 @@ SubjectPublicKeyInfo ::= SEQUENCE {
subjectPublicKey BIT STRING subjectPublicKey BIT STRING
} }
Extension ::= SEQUENCE { -- XXX Should be _OTHER-NAME ::= _TYPE-IDENTIFIER
extnID OBJECT IDENTIFIER, _OTHER-NAME ::= CLASS {
critical BOOLEAN OPTIONAL, -- DEFAULT FALSE XXX &id OBJECT IDENTIFIER UNIQUE,
extnValue OCTET STRING &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 Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension
@@ -285,16 +344,8 @@ DHParameter ::= SEQUENCE {
DHPublicKey ::= INTEGER DHPublicKey ::= INTEGER
OtherName ::= SEQUENCE {
type-id OBJECT IDENTIFIER,
value [0] EXPLICIT heim_any
}
GeneralName ::= CHOICE { GeneralName ::= CHOICE {
otherName [0] IMPLICIT -- OtherName -- SEQUENCE { otherName [0] IMPLICIT OtherName,
type-id OBJECT IDENTIFIER,
value [0] EXPLICIT heim_any
},
rfc822Name [1] IMPLICIT IA5String, rfc822Name [1] IMPLICIT IA5String,
dNSName [2] IMPLICIT IA5String, dNSName [2] IMPLICIT IA5String,
-- x400Address [3] IMPLICIT ORAddress,-- -- x400Address [3] IMPLICIT ORAddress,--
@@ -336,7 +387,7 @@ PolicyQualifierId ::= OBJECT IDENTIFIER -- ( id-qt-cps | id-qt-unotice )
PolicyQualifierInfo ::= SEQUENCE { PolicyQualifierInfo ::= SEQUENCE {
policyQualifierId PolicyQualifierId, policyQualifierId PolicyQualifierId,
qualifier heim_any -- ANY DEFINED BY policyQualifierId qualifier HEIM_ANY -- ANY DEFINED BY policyQualifierId
} }
PolicyQualifierInfos ::= SEQUENCE SIZE (1..MAX) OF PolicyQualifierInfo PolicyQualifierInfos ::= SEQUENCE SIZE (1..MAX) OF PolicyQualifierInfo
@@ -400,18 +451,18 @@ SubjectKeyIdentifier ::= KeyIdentifier
id-x509-ce-basicConstraints OBJECT IDENTIFIER ::= { id-x509-ce 19 } id-x509-ce-basicConstraints OBJECT IDENTIFIER ::= { id-x509-ce 19 }
BasicConstraints ::= SEQUENCE { BasicConstraints ::= SEQUENCE {
cA BOOLEAN OPTIONAL -- DEFAULT FALSE --, cA BOOLEAN DEFAULT FALSE,
pathLenConstraint INTEGER (0..4294967295) OPTIONAL pathLenConstraint INTEGER (0..4294967295) OPTIONAL
} }
id-x509-ce-nameConstraints OBJECT IDENTIFIER ::= { id-x509-ce 30 } id-x509-ce-nameConstraints OBJECT IDENTIFIER ::= { id-x509-ce 30 }
BaseDistance ::= INTEGER -- (0..MAX) -- BaseDistance ::= INTEGER (0..4294967295)
GeneralSubtree ::= SEQUENCE { GeneralSubtree ::= SEQUENCE {
base GeneralName, base GeneralName,
minimum [0] IMPLICIT -- BaseDistance -- INTEGER OPTIONAL -- DEFAULT 0 --, minimum [0] IMPLICIT BaseDistance DEFAULT 0,
maximum [1] IMPLICIT -- BaseDistance -- INTEGER OPTIONAL maximum [1] IMPLICIT BaseDistance OPTIONAL
} }
GeneralSubtrees ::= SEQUENCE -- SIZE (1..MAX) -- OF GeneralSubtree GeneralSubtrees ::= SEQUENCE -- SIZE (1..MAX) -- OF GeneralSubtree
@@ -462,9 +513,9 @@ DistributionPointName ::= CHOICE {
} }
DistributionPoint ::= SEQUENCE { DistributionPoint ::= SEQUENCE {
distributionPoint [0] IMPLICIT heim_any -- DistributionPointName -- OPTIONAL, distributionPoint [0] IMPLICIT HEIM_ANY -- DistributionPointName -- OPTIONAL,
reasons [1] IMPLICIT heim_any -- DistributionPointReasonFlags -- OPTIONAL, reasons [1] IMPLICIT HEIM_ANY -- DistributionPointReasonFlags -- OPTIONAL,
cRLIssuer [2] IMPLICIT heim_any -- GeneralNames -- OPTIONAL cRLIssuer [2] IMPLICIT HEIM_ANY -- GeneralNames -- OPTIONAL
} }
CRLDistributionPoints ::= SEQUENCE SIZE (1..MAX) OF DistributionPoint 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-xmppAddr OBJECT IDENTIFIER ::= { id-pkix-on 5 }
id-pkix-on-dnsSRV OBJECT IDENTIFIER ::= { id-pkix-on 7 } 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 -- EKUs
id-pkix-kp OBJECT IDENTIFIER ::= { id-pkix 3 } id-pkix-kp OBJECT IDENTIFIER ::= { id-pkix 3 }
id-pkix-kp-serverAuth OBJECT IDENTIFIER ::= { id-pkix-kp 1 } 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-msft-kp-msUPN OBJECT IDENTIFIER ::= { id-msft 20 2 3 }
id-pkix-pe OBJECT IDENTIFIER ::= { id-pkix 1 } id-pkix-pe OBJECT IDENTIFIER ::= { id-pkix 1 }
id-pkix-pe-authorityInfoAccess OBJECT IDENTIFIER ::= { id-pkix-pe 1 } id-pkix-pe-authorityInfoAccess OBJECT IDENTIFIER ::= { id-pkix-pe 1 }
AccessDescription ::= SEQUENCE { AccessDescription ::= SEQUENCE {
@@ -669,6 +749,350 @@ ProxyCertInfo ::= SEQUENCE {
proxyPolicy ProxyPolicy 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 --- U.S. Federal PKI Common Policy Framework
-- Card Authentication key -- Card Authentication key
id-uspkicommon-card-id OBJECT IDENTIFIER ::= { 2 16 840 1 101 3 6 6 } 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 DEFINITIONS IMPLICIT TAGS ::= BEGIN
IMPORTS 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 EnvelopedData
FROM cms -- [CMS] FROM cms -- [CMS]
{ iso(1) member-body(2) us(840) rsadsi(113549) { 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) iso(1) identified-organization(3) dod(6) internet(1) security(5)
mechanisms(5) pkix(7) on(8) 4 } mechanisms(5) pkix(7) on(8) 4 }
HardwareModuleName ::= SEQUENCE { -- Moved to rfc2459.asn1 so we can have the OtherName type decode it
hwType OBJECT IDENTIFIER, -- automatically:
hwSerialNum OCTET STRING } --HardwareModuleName ::= SEQUENCE {
-- hwType OBJECT IDENTIFIER,
-- hwSerialNum OCTET STRING }
END END

View File

@@ -68,6 +68,8 @@ enum typetype {
typedef enum typetype Typetype; typedef enum typetype Typetype;
struct type; struct type;
struct value;
struct typereference;
struct value { struct value {
enum { booleanvalue, enum { booleanvalue,
@@ -82,6 +84,7 @@ struct value {
char *stringvalue; char *stringvalue;
struct objid *objectidentifiervalue; struct objid *objectidentifiervalue;
} u; } u;
struct symbol *s;
}; };
struct member { struct member {
@@ -117,15 +120,82 @@ struct range {
int64_t max; int64_t max;
}; };
enum ctype { CT_CONTENTS, CT_USER } ; enum ctype { CT_CONTENTS, CT_USER, CT_TABLE_CONSTRAINT } ;
struct constraint_spec; 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 { struct type {
Typetype type; Typetype type;
struct memhead *members; struct memhead *members;
struct symbol *symbol; struct symbol *symbol;
struct type *subtype; struct type *subtype;
struct typereference typeref; /* For type fields */
IOSClass *formal_parameter;
IOSObjectSet *actual_parameter;
struct tagtype tag; struct tagtype tag;
struct range *range; struct range *range;
struct constraint_spec *constraint; struct constraint_spec *constraint;
@@ -134,12 +204,18 @@ struct type {
typedef struct type Type; typedef struct type Type;
struct component_relation_constraint {
char *objectname;
char *membername;
};
struct constraint_spec { struct constraint_spec {
enum ctype ctype; enum ctype ctype;
union { union {
struct { struct {
Type *type; Type *type;
struct value *encoding; struct value *encoding;
struct component_relation_constraint crel;
} content; } content;
} u; } u;
}; };
@@ -153,13 +229,17 @@ struct objid {
struct symbol { struct symbol {
char *name; char *name;
char *gen_name; char *gen_name;
enum { SUndefined, SValue, Stype } stype; enum { SUndefined, SValue, Stype, Sparamtype, Sclass, Sobj, Sobjset } stype;
struct value *value; struct value *value;
Type *type; Type *type;
IOSClass *iosclass;
IOSObject *object;
IOSObjectSet *objectset;
HEIM_TAILQ_ENTRY(symbol) symlist; HEIM_TAILQ_ENTRY(symbol) symlist;
unsigned int emitted_declaration:1; unsigned int emitted_declaration:1;
unsigned int emitted_definition:1; unsigned int emitted_definition:1;
unsigned int emitted_tag_enums:1; unsigned int emitted_tag_enums:1;
unsigned int emitted_template:1;
}; };
typedef struct symbol Symbol; typedef struct symbol Symbol;

View File

@@ -1,8 +1,5 @@
TCG DEFINITIONS ::= BEGIN TCG DEFINITIONS ::= BEGIN
IMPORTS AlgorithmIdentifier FROM rfc2459;
-- BEGIN Heimdal commentary -- BEGIN Heimdal commentary
-- --
-- Copy-pasted from section 4 of -- 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 -- https://trustedcomputinggroup.org/wp-content/uploads/Credential_Profile_EK_V2.0_R14_published.pdf
-- and adjusted to compile as follows: -- 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 -- - Extensibility markers added to all SEQUENCEs as per the TCG's spec they
-- reserve the right to add fields in the future. -- reserve the right to add fields in the future.
-- - Information Object System annotations commented out (Heimdal does not -- - Information Object System annotations commented out (Heimdal does not
-- support them) -- support them)
--
-- - Types sorted topologically (at the time I did that the Heimdal ASN.1 -- - Types sorted topologically (at the time I did that the Heimdal ASN.1
-- compiler wouldn't do that on its own) -- compiler wouldn't do that on its own)
--
-- - Two otherwise equal ENUMERATED types share a definition now (at the time -- - Two otherwise equal ENUMERATED types share a definition now (at the time
-- the Heimdal ASN.1 compiler did not prefix labels of ENUMERATED types) -- 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) -- 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 END

File diff suppressed because it is too large Load Diff

View File

@@ -4,7 +4,7 @@ TEST DEFINITIONS ::=
BEGIN BEGIN
IMPORTS heim_any FROM heim; IMPORTS HEIM_ANY FROM heim;
-- Check that we handle out of order definitions. -- Check that we handle out of order definitions.
-- The compiler should emit the definition of TESTOutOfOrderBar before that of -- The compiler should emit the definition of TESTOutOfOrderBar before that of
@@ -103,7 +103,7 @@ TESTAllocInner ::= SEQUENCE {
TESTAlloc ::= SEQUENCE { TESTAlloc ::= SEQUENCE {
tagless TESTAllocInner OPTIONAL, tagless TESTAllocInner OPTIONAL,
three [1] INTEGER (-2147483648..2147483647), three [1] INTEGER (-2147483648..2147483647),
tagless2 heim_any OPTIONAL tagless2 HEIM_ANY OPTIONAL
} }
TESTOptional ::= SEQUENCE { TESTOptional ::= SEQUENCE {
@@ -117,22 +117,22 @@ TESTENCODEDBY ::= OCTET STRING ( ENCODED BY
{ joint-iso-itu-t(2) asn(1) ber-derived(2) distinguished-encoding(1) } { 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) 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) } { joint-iso-itu-t(2) asn(1) ber-derived(2) distinguished-encoding(1) }
) )
TESTCONTAININGENCODEDBY2 ::= OCTET STRING ( testContainingEncodedBy2 ::= OCTET STRING (
CONTAINING INTEGER ENCODED BY TESTDer 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 }) -- TESTUSERCONSTRAINED2 ::= OCTET STRING (CONSTRAINED BY { TESTInteger })
-- TESTUSERCONSTRAINED3 ::= OCTET STRING (CONSTRAINED BY { INTEGER }) -- TESTUSERCONSTRAINED3 ::= OCTET STRING (CONSTRAINED BY { INTEGER })
-- TESTUSERCONSTRAINED4 ::= OCTET STRING (CONSTRAINED BY { INTEGER : 1 }) -- TESTUSERCONSTRAINED4 ::= OCTET STRING (CONSTRAINED BY { INTEGER : 1 })
@@ -250,4 +250,40 @@ TESTLargeBitString ::= BIT STRING {
TESTMechType::= OBJECT IDENTIFIER TESTMechType::= OBJECT IDENTIFIER
TESTMechTypeList ::= SEQUENCE OF TESTMechType 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 END

View File

@@ -2,11 +2,11 @@
GSS-API DEFINITIONS ::= BEGIN GSS-API DEFINITIONS ::= BEGIN
IMPORTS heim_any_set FROM heim; IMPORTS HEIM_ANY_SET FROM heim;
GSSAPIContextToken ::= [APPLICATION 0] IMPLICIT SEQUENCE { GSSAPIContextToken ::= [APPLICATION 0] IMPLICIT SEQUENCE {
thisMech OBJECT IDENTIFIER, 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_HDB_EntryOrAlias.x \
asn1_KeyRotation.x \ asn1_KeyRotation.x \
asn1_KeyRotationFlags.x \ asn1_KeyRotationFlags.x \
asn1_hdb_entry.x \ asn1_HDB_entry.x \
asn1_hdb_entry_alias.x \ asn1_HDB_entry_alias.x \
asn1_hdb_keyset.x \ asn1_HDB_keyset.x \
asn1_Keys.x asn1_Keys.x
CLEANFILES = $(BUILT_SOURCES) $(gen_files_hdb) \ 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; size_t len = 0;
int ret; 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) if (ret == 0 && value->length != len)
krb5_abortx(context, "internal asn.1 encoder error"); krb5_abortx(context, "internal asn.1 encoder error");
return ret; return ret;
@@ -74,7 +74,7 @@ hdb_entry2value(krb5_context context, const hdb_entry *ent, krb5_data *value)
int int
hdb_value2entry(krb5_context context, krb5_data *value, hdb_entry *ent) 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 int
@@ -85,7 +85,7 @@ hdb_entry_alias2value(krb5_context context,
size_t len = 0; size_t len = 0;
int ret; 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); alias, &len, ret);
if (ret == 0 && value->length != len) if (ret == 0 && value->length != len)
krb5_abortx(context, "internal asn.1 encoder error"); krb5_abortx(context, "internal asn.1 encoder error");
@@ -96,7 +96,7 @@ int
hdb_value2entry_alias(krb5_context context, krb5_data *value, hdb_value2entry_alias(krb5_context context, krb5_data *value,
hdb_entry_alias *ent) 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) { (flags & (HDB_F_CANON|HDB_F_GET_ANY)) == 0) {
/* `principal' was alias but canon not req'd */ /* `principal' was alias but canon not req'd */
free_hdb_entry(&entry->entry); free_HDB_entry(&entry->entry);
ret = HDB_ERR_NOENTRY; 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); code = hdb_entry_get_aliases(&oldentry, &aliases);
if (code || aliases == NULL) { if (code || aliases == NULL) {
free_hdb_entry(&oldentry); free_HDB_entry(&oldentry);
return code; return code;
} }
for (i = 0; i < aliases->aliases.len; i++) { 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); krb5_data_free(&akey);
} }
if (code) { if (code) {
free_hdb_entry(&oldentry); free_HDB_entry(&oldentry);
return code; return code;
} }
} }
free_hdb_entry(&oldentry); free_HDB_entry(&oldentry);
return 0; return 0;
} }
@@ -790,7 +790,7 @@ derive_keys_for_kr(krb5_context context,
if (ret == 0) if (ret == 0)
ret = hdb_install_keyset(context, &h->entry, is_current_keyset, &dks); ret = hdb_install_keyset(context, &h->entry, is_current_keyset, &dks);
free_hdb_keyset(&dks); free_HDB_keyset(&dks);
return ret; return ret;
} }
@@ -1468,3 +1468,111 @@ hdb_fetch_kvno(krb5_context context,
krb5_set_error_message(context, ret, "no such entry found in hdb"); krb5_set_error_message(context, ret, "no such entry found in hdb");
return ret; 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: out:
if (ret) { if (ret) {
free_hdb_entry(&entry->entry); free_HDB_entry(&entry->entry);
memset(&entry->entry, 0, sizeof(entry->entry)); memset(&entry->entry, 0, sizeof(entry->entry));
} }
krb5_kt_free_entry(context, &ktentry); krb5_kt_free_entry(context, &ktentry);

View File

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

View File

@@ -99,14 +99,14 @@ HDB-Ext-Aliases ::= SEQUENCE {
Keys ::= SEQUENCE OF Key Keys ::= SEQUENCE OF Key
hdb_keyset ::= SEQUENCE { HDB_keyset ::= SEQUENCE {
kvno[0] INTEGER (0..4294967295), kvno[0] INTEGER (0..4294967295),
keys[1] Keys, keys[1] Keys,
set-time[2] KerberosTime OPTIONAL, -- time this keyset was created/set 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 -- 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 -- Just for convenience, for encoding this as TL data in lib/kadm5
HDB-EncTypeList ::= SEQUENCE OF INTEGER (0..4294967295) HDB-EncTypeList ::= SEQUENCE OF INTEGER (0..4294967295)
hdb_entry ::= SEQUENCE { HDB_entry ::= SEQUENCE {
principal[0] Principal OPTIONAL, -- this is optional only principal[0] Principal OPTIONAL, -- this is optional only
-- for compatibility with libkrb5 -- for compatibility with libkrb5
kvno[1] INTEGER (0..4294967295), kvno[1] INTEGER (0..4294967295),
@@ -236,13 +236,13 @@ hdb_entry ::= SEQUENCE {
extensions[13] HDB-extensions OPTIONAL extensions[13] HDB-extensions OPTIONAL
} }
hdb_entry_alias ::= [APPLICATION 0] SEQUENCE { HDB_entry_alias ::= [APPLICATION 0] SEQUENCE {
principal[0] Principal OPTIONAL principal[0] Principal OPTIONAL
} }
HDB-EntryOrAlias ::= CHOICE { HDB-EntryOrAlias ::= CHOICE {
entry hdb_entry, entry HDB_entry,
alias hdb_entry_alias alias HDB_entry_alias
} }
END 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); memset (k->key.keyvalue.data, 0, k->key.keyvalue.length);
} }
free_hdb_entry(&ent->entry); free_HDB_entry(&ent->entry);
} }
krb5_error_code krb5_error_code

View File

@@ -44,6 +44,9 @@
#include <heim_asn1.h> #include <heim_asn1.h>
#include <hdb_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; struct hdb_dbinfo;

View File

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

View File

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

View File

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

View File

@@ -68,7 +68,7 @@ check_HDB_EntryOrAlias(krb5_context context)
NULL); NULL);
if (ret) if (ret)
krb5_err(context, 1, ret, "krb5_make_principal"); 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) if (ret)
krb5_err(context, 1, ret, "encode_HDB_EntryOrAlias"); krb5_err(context, 1, ret, "encode_HDB_EntryOrAlias");
if (v.length != len) if (v.length != len)
@@ -79,7 +79,7 @@ check_HDB_EntryOrAlias(krb5_context context)
if (v.length != len) if (v.length != len)
abort(); abort();
free_HDB_EntryOrAlias(&eoa); free_HDB_EntryOrAlias(&eoa);
free_hdb_entry_alias(&alias); free_HDB_entry_alias(&alias);
krb5_data_free(&v); krb5_data_free(&v);
ret = krb5_make_principal(context, &entry.principal, "KTH.SE", "foo", 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"); krb5_err(context, 1, ret, "krb5_make_principal");
entry.kvno = 5; entry.kvno = 5;
entry.flags.initial = 1; 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) if (ret)
krb5_err(context, 1, ret, "encode_HDB_EntryOrAlias"); krb5_err(context, 1, ret, "encode_HDB_EntryOrAlias");
if (v.length != len) if (v.length != len)
@@ -99,7 +99,7 @@ check_HDB_EntryOrAlias(krb5_context context)
if (v.length != len) if (v.length != len)
abort(); abort();
free_HDB_EntryOrAlias(&eoa); free_HDB_EntryOrAlias(&eoa);
free_hdb_entry(&entry); free_HDB_entry(&entry);
krb5_data_free(&v); krb5_data_free(&v);
} }

View File

@@ -104,7 +104,7 @@ main(int argc, char **argv)
krb5_free_principal (context, principal); 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) if (ret)
krb5_errx(context, 1, "encode keyset"); krb5_errx(context, 1, "encode keyset");
if (len != length) if (len != length)

View File

@@ -92,6 +92,7 @@ HEIMDAL_HDB_1.0 {
hdb_value2entry_alias; hdb_value2entry_alias;
hdb_write_master_key; hdb_write_master_key;
length_hdb_keyset; length_hdb_keyset;
length_HDB_keyset;
hdb_interface_version; hdb_interface_version;
initialize_hdb_error_table_r; initialize_hdb_error_table_r;
@@ -113,6 +114,8 @@ HEIMDAL_HDB_1.0 {
copy_HDB_EncTypeList; copy_HDB_EncTypeList;
copy_hdb_entry; copy_hdb_entry;
copy_hdb_entry_alias; copy_hdb_entry_alias;
copy_HDB_entry;
copy_HDB_entry_alias;
copy_HDB_EntryOrAlias; copy_HDB_EntryOrAlias;
copy_HDB_extensions; copy_HDB_extensions;
copy_HDB_Ext_KeyRotation; copy_HDB_Ext_KeyRotation;
@@ -122,6 +125,8 @@ HEIMDAL_HDB_1.0 {
decode_HDB_EncTypeList; decode_HDB_EncTypeList;
decode_hdb_entry; decode_hdb_entry;
decode_hdb_entry_alias; decode_hdb_entry_alias;
decode_HDB_entry;
decode_HDB_entry_alias;
decode_HDB_EntryOrAlias; decode_HDB_EntryOrAlias;
decode_HDB_Ext_Aliases; decode_HDB_Ext_Aliases;
decode_HDB_extension; decode_HDB_extension;
@@ -132,18 +137,23 @@ HEIMDAL_HDB_1.0 {
encode_HDB_EncTypeList; encode_HDB_EncTypeList;
encode_hdb_entry; encode_hdb_entry;
encode_hdb_entry_alias; encode_hdb_entry_alias;
encode_HDB_entry;
encode_HDB_entry_alias;
encode_HDB_EntryOrAlias; encode_HDB_EntryOrAlias;
encode_HDB_Ext_Aliases; encode_HDB_Ext_Aliases;
encode_HDB_extension; encode_HDB_extension;
encode_HDB_Ext_KeyRotation; encode_HDB_Ext_KeyRotation;
encode_HDB_Ext_PKINIT_acl; encode_HDB_Ext_PKINIT_acl;
encode_hdb_keyset; encode_hdb_keyset;
encode_HDB_keyset;
encode_Key; encode_Key;
encode_Keys; encode_Keys;
free_Event; free_Event;
free_HDB_EncTypeList; free_HDB_EncTypeList;
free_hdb_entry; free_hdb_entry;
free_hdb_entry_alias; free_hdb_entry_alias;
free_HDB_entry;
free_HDB_entry_alias;
free_HDB_EntryOrAlias; free_HDB_EntryOrAlias;
free_HDB_Ext_Aliases; free_HDB_Ext_Aliases;
free_HDB_extension; free_HDB_extension;
@@ -152,6 +162,7 @@ HEIMDAL_HDB_1.0 {
free_HDB_Ext_KeySet; free_HDB_Ext_KeySet;
free_HDB_Ext_PKINIT_acl; free_HDB_Ext_PKINIT_acl;
free_hdb_keyset; free_hdb_keyset;
free_HDB_keyset;
free_Key; free_Key;
free_Keys; free_Keys;
free_Salt; free_Salt;
@@ -162,6 +173,8 @@ HEIMDAL_HDB_1.0 {
length_HDB_EncTypeList; length_HDB_EncTypeList;
length_hdb_entry; length_hdb_entry;
length_hdb_entry_alias; length_hdb_entry_alias;
length_HDB_entry;
length_HDB_entry_alias;
length_HDB_EntryOrAlias; length_HDB_EntryOrAlias;
length_HDB_Ext_Aliases; length_HDB_Ext_Aliases;
length_HDB_extension; 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"); _hx509_abort("internal ASN.1 encoder error");
ret = hx509_ca_tbs_add_san_otherName(context, tbs, ret = hx509_ca_tbs_add_san_otherName(context, tbs,
&asn1_oid_id_on_permanentIdentifier, &asn1_oid_id_pkix_on_permanentIdentifier,
&os); &os);
free(os.data); free(os.data);
return ret; return ret;
@@ -1595,16 +1595,7 @@ add_extension(hx509_context context,
memset(&ext, 0, sizeof(ext)); memset(&ext, 0, sizeof(ext));
if (critical_flag) { ext.critical = 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;
}
ret = der_copy_oid(oid, &ext.extnID); ret = der_copy_oid(oid, &ext.extnID);
if (ret) { if (ret) {
hx509_set_error_string(context, 0, ret, "Out of memory"); hx509_set_error_string(context, 0, ret, "Out of memory");
@@ -1975,13 +1966,12 @@ ca_sign(hx509_context context,
/* Add BasicConstraints */ /* Add BasicConstraints */
{ {
BasicConstraints bc; BasicConstraints bc;
int aCA = 1;
unsigned int path; unsigned int path;
memset(&bc, 0, sizeof(bc)); memset(&bc, 0, sizeof(bc));
if (tbs->flags.ca) { if (tbs->flags.ca) {
bc.cA = &aCA; bc.cA = 1;
if (tbs->pathLenConstraint >= 0) { if (tbs->pathLenConstraint >= 0) {
path = tbs->pathLenConstraint; path = tbs->pathLenConstraint;
bc.pathLenConstraint = &path; bc.pathLenConstraint = &path;

View File

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

View File

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

View File

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

View File

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

View File

@@ -1238,7 +1238,7 @@ struct {
{ &asn1_oid_id_pkinit_san, { &asn1_oid_id_pkinit_san,
"KerberosPrincipalName", "KerberosPrincipalName",
_hx509_unparse_KRB5PrincipalName }, _hx509_unparse_KRB5PrincipalName },
{ &asn1_oid_id_on_permanentIdentifier, { &asn1_oid_id_pkix_on_permanentIdentifier,
"PermanentIdentifier", "PermanentIdentifier",
_hx509_unparse_PermanentIdentifier }, _hx509_unparse_PermanentIdentifier },
{ &asn1_oid_id_on_hardwareModuleName, { &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"); printf("\tlength of der data isn't same as extension\n");
validate_print(ctx, HX509_VALIDATE_F_VERBOSE, 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) if (b.pathLenConstraint)
validate_print(ctx, HX509_VALIDATE_F_VERBOSE, validate_print(ctx, HX509_VALIDATE_F_VERBOSE,
"\tpathLenConstraint: %d\n", *b.pathLenConstraint); "\tpathLenConstraint: %d\n", *b.pathLenConstraint);
if (b.cA) { if (b.cA) {
if (*b.cA) { if (!e->critical)
if (!e->critical) validate_print(ctx, HX509_VALIDATE_F_VALIDATE,
validate_print(ctx, HX509_VALIDATE_F_VALIDATE, "Is a CA and not BasicConstraints CRITICAL\n");
"Is a CA and not BasicConstraints CRITICAL\n"); status->isca = 1;
status->isca = 1;
}
else
validate_print(ctx, HX509_VALIDATE_F_VALIDATE,
"cA is FALSE, not allowed to be\n");
} }
free_BasicConstraints(&b); free_BasicConstraints(&b);

View File

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

View File

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

View File

@@ -122,6 +122,8 @@ struct mbuf;
#include <krb5_asn1.h> #include <krb5_asn1.h>
typedef Krb5Int32 krb5int32;
typedef Krb5UInt32 krb5uint32;
#include <pkinit_asn1.h> #include <pkinit_asn1.h>
struct send_to_kdc; 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) if(enc->transited.tr_type == 0 && enc->transited.contents.length == 0)
return 0; return 0;
if(enc->transited.tr_type != DOMAIN_X500_COMPRESS) if(enc->transited.tr_type != domain_X500_Compress)
return KRB5KDC_ERR_TRTYPE_NOSUPP; return KRB5KDC_ERR_TRTYPE_NOSUPP;
if(enc->transited.contents.length == 0) if(enc->transited.contents.length == 0)