update ticket5 from heimdal
authorDerrick Brashear <shadow@dementia.org>
Wed, 30 Jun 2010 19:35:38 +0000 (15:35 -0400)
committerDerrick Brashear <shadow@dementia.org>
Thu, 1 Jul 2010 16:33:43 +0000 (09:33 -0700)
includes updated instructions for updating.
note that gen_glue.c in lib/asn1 has a bug which omits
a needed newline in the "const struct units * asn1_%s_units(void);",
line.

FIXES 127554

Change-Id: Ibc880bf51419d51de40b33d8c43122e592971b0b
Reviewed-on: http://gerrit.openafs.org/2306
Reviewed-by: Derrick Brashear <shadow@dementia.org>
Tested-by: Derrick Brashear <shadow@dementia.org>

src/rxkad/README.v5
src/rxkad/asn1-common.h [deleted file]
src/rxkad/asn1_err.h
src/rxkad/der-protos.h [new file with mode: 0644]
src/rxkad/der.h
src/rxkad/ticket5.c
src/rxkad/v5der.c
src/rxkad/v5gen.c
src/rxkad/v5gen.h

index 379372f..5e260d1 100644 (file)
@@ -38,12 +38,12 @@ export htree otree
 (cd $htree/lib/asn1 ; \
  echo '#include "asn1_err.h"'; 
  echo '#include <errno.h>'; 
- cat der_get.c \
+ cat  timegm.c \
+ der_get.c \
  der_put.c \
  der_free.c \
  der_length.c \
  der_copy.c \
- timegm.c \
     )  \
 | grep -v 'include "der_locl.h"' \
 | grep -v 'include <version.h>' \
@@ -54,8 +54,16 @@ export htree otree
 grep -v 'struct units'  $hotree/lib/asn1/krb5_asn1.h \
    > $otree/src/rxkad/v5gen.h
 
+cp  $hotree/lib/asn1/der-protos.h \
+   > $otree/src/rxkad/der-protos.h
+
+cp  $hotree/lib/asn1/asn1_err.h \
+   > $otree/src/rxkad/asn1_err.h
+
 (cd $hotree/lib/asn1 ; \
- cat asn1_Ticket.c \
+ cat asn1_krb5int32.c \
+    asn1_Ticket.c \
+    asn1_AuthorizationDataElement.c \
     asn1_EncryptedData.c \
     asn1_PrincipalName.c \
     asn1_HostAddresses.c \
@@ -70,11 +78,16 @@ grep -v 'struct units'  $hotree/lib/asn1/krb5_asn1.h \
     asn1_ENCTYPE.c \
     asn1_NAME_TYPE.c \
     ) \
+ | grep -v 'include <krb5-types.h>' \
  | grep -v 'include <krb5_asn1.h>' \
+ | grep -v 'include <krb5_asn1-priv.h>' \
  | grep -v 'include <der.h>' \
+ | grep -v 'include <der-private.h>' \
  | grep -v 'include <parse_units.h>' \
+ | grep -v 'include <asn1-template.h>' \
  | perl \
-   -e '$f=0; while(<>){$f=1 if(/struct units/);print if($f eq 0);$f=0 if(/^};/);}' \
+   -e '$f=0; while(<>){$f=1 if(/struct units/);print if($f eq 0);$f=0 if(/^}/);}' \
+ | indent -npro -nbad -bap -nbc -br -ce -cd4 -brs -ncdb -di2 -ndj -nfc1 -i4 -lp -npcs -psl -sc -nsob \
  | cat > $otree/src/rxkad/v5gen.c
 
 ( \
diff --git a/src/rxkad/asn1-common.h b/src/rxkad/asn1-common.h
deleted file mode 100644 (file)
index 6f470d7..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-/* $Id$ */
-
-#include <stddef.h>
-#include <time.h>
-
-#ifndef __asn1_common_definitions__
-#define __asn1_common_definitions__
-
-typedef struct octet_string {
-    size_t length;
-    void *data;
-} octet_string;
-
-typedef char *general_string;
-
-typedef struct oid {
-    size_t length;
-    unsigned *components;
-} oid;
-
-#endif
index 78e671d..63cfbfa 100644 (file)
@@ -1,23 +1,40 @@
-/* Generated from ../../../lib/asn1/asn1_err.et */
+/* Generated from asn1_err.et */
 /* $Id$ */
 
 #ifndef __asn1_err_h__
 #define __asn1_err_h__
 
-typedef enum asn1_error_number {
-    ERROR_TABLE_BASE_asn1 = 1859794432,
-    asn1_err_base = 1859794432,
-    ASN1_BAD_TIMEFORMAT = 1859794432,
-    ASN1_MISSING_FIELD = 1859794433,
-    ASN1_MISPLACED_FIELD = 1859794434,
-    ASN1_TYPE_MISMATCH = 1859794435,
-    ASN1_OVERFLOW = 1859794436,
-    ASN1_OVERRUN = 1859794437,
-    ASN1_BAD_ID = 1859794438,
-    ASN1_BAD_LENGTH = 1859794439,
-    ASN1_BAD_FORMAT = 1859794440,
-    ASN1_PARSE_ERROR = 1859794441,
-    asn1_num_errors = 10
+struct et_list;
+
+void initialize_asn1_error_table_r(struct et_list **);
+
+void initialize_asn1_error_table(void);
+#define init_asn1_err_tbl initialize_asn1_error_table
+
+typedef enum asn1_error_number{
+       ASN1_BAD_TIMEFORMAT = 1859794432,
+       ASN1_MISSING_FIELD = 1859794433,
+       ASN1_MISPLACED_FIELD = 1859794434,
+       ASN1_TYPE_MISMATCH = 1859794435,
+       ASN1_OVERFLOW = 1859794436,
+       ASN1_OVERRUN = 1859794437,
+       ASN1_BAD_ID = 1859794438,
+       ASN1_BAD_LENGTH = 1859794439,
+       ASN1_BAD_FORMAT = 1859794440,
+       ASN1_PARSE_ERROR = 1859794441,
+       ASN1_EXTRA_DATA = 1859794442,
+       ASN1_BAD_CHARACTER = 1859794443,
+       ASN1_MIN_CONSTRAINT = 1859794444,
+       ASN1_MAX_CONSTRAINT = 1859794445,
+       ASN1_EXACT_CONSTRAINT = 1859794446,
+       ASN1_INDEF_OVERRUN = 1859794447,
+       ASN1_INDEF_UNDERRUN = 1859794448,
+       ASN1_GOT_BER = 1859794449,
+       ASN1_INDEF_EXTRA_DATA = 1859794450
 } asn1_error_number;
 
+#define ERROR_TABLE_BASE_asn1 1859794432
+
+#define COM_ERR_BINDDOMAIN_asn1 "heim_com_err1859794432"
+
 #endif /* __asn1_err_h__ */
diff --git a/src/rxkad/der-protos.h b/src/rxkad/der-protos.h
new file mode 100644 (file)
index 0000000..d5e9310
--- /dev/null
@@ -0,0 +1,583 @@
+/* This is a generated file */
+#ifndef __der_protos_h__
+#define __der_protos_h__
+
+#include <stdarg.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int
+copy_heim_any (
+       const heim_any */*from*/,
+       heim_any */*to*/);
+
+int
+copy_heim_any_set (
+       const heim_any_set */*from*/,
+       heim_any_set */*to*/);
+
+int
+decode_heim_any (
+       const unsigned char */*p*/,
+       size_t /*len*/,
+       heim_any */*data*/,
+       size_t */*size*/);
+
+int
+decode_heim_any_set (
+       const unsigned char */*p*/,
+       size_t /*len*/,
+       heim_any_set */*data*/,
+       size_t */*size*/);
+
+int
+der_copy_bit_string (
+       const heim_bit_string */*from*/,
+       heim_bit_string */*to*/);
+
+int
+der_copy_bmp_string (
+       const heim_bmp_string */*from*/,
+       heim_bmp_string */*to*/);
+
+int
+der_copy_general_string (
+       const heim_general_string */*from*/,
+       heim_general_string */*to*/);
+
+int
+der_copy_heim_integer (
+       const heim_integer */*from*/,
+       heim_integer */*to*/);
+
+int
+der_copy_ia5_string (
+       const heim_printable_string */*from*/,
+       heim_printable_string */*to*/);
+
+int
+der_copy_octet_string (
+       const heim_octet_string */*from*/,
+       heim_octet_string */*to*/);
+
+int
+der_copy_oid (
+       const heim_oid */*from*/,
+       heim_oid */*to*/);
+
+int
+der_copy_printable_string (
+       const heim_printable_string */*from*/,
+       heim_printable_string */*to*/);
+
+int
+der_copy_universal_string (
+       const heim_universal_string */*from*/,
+       heim_universal_string */*to*/);
+
+int
+der_copy_utf8string (
+       const heim_utf8_string */*from*/,
+       heim_utf8_string */*to*/);
+
+int
+der_copy_visible_string (
+       const heim_visible_string */*from*/,
+       heim_visible_string */*to*/);
+
+void
+der_free_bit_string (heim_bit_string */*k*/);
+
+void
+der_free_bmp_string (heim_bmp_string */*k*/);
+
+void
+der_free_general_string (heim_general_string */*str*/);
+
+void
+der_free_heim_integer (heim_integer */*k*/);
+
+void
+der_free_ia5_string (heim_ia5_string */*str*/);
+
+void
+der_free_octet_string (heim_octet_string */*k*/);
+
+void
+der_free_oid (heim_oid */*k*/);
+
+void
+der_free_printable_string (heim_printable_string */*str*/);
+
+void
+der_free_universal_string (heim_universal_string */*k*/);
+
+void
+der_free_utf8string (heim_utf8_string */*str*/);
+
+void
+der_free_visible_string (heim_visible_string */*str*/);
+
+int
+der_get_bit_string (
+       const unsigned char */*p*/,
+       size_t /*len*/,
+       heim_bit_string */*data*/,
+       size_t */*size*/);
+
+int
+der_get_bmp_string (
+       const unsigned char */*p*/,
+       size_t /*len*/,
+       heim_bmp_string */*data*/,
+       size_t */*size*/);
+
+int
+der_get_boolean (
+       const unsigned char */*p*/,
+       size_t /*len*/,
+       int */*data*/,
+       size_t */*size*/);
+
+const char *
+der_get_class_name (unsigned /*num*/);
+
+int
+der_get_class_num (const char */*name*/);
+
+int
+der_get_general_string (
+       const unsigned char */*p*/,
+       size_t /*len*/,
+       heim_general_string */*str*/,
+       size_t */*size*/);
+
+int
+der_get_generalized_time (
+       const unsigned char */*p*/,
+       size_t /*len*/,
+       time_t */*data*/,
+       size_t */*size*/);
+
+int
+der_get_heim_integer (
+       const unsigned char */*p*/,
+       size_t /*len*/,
+       heim_integer */*data*/,
+       size_t */*size*/);
+
+int
+der_get_ia5_string (
+       const unsigned char */*p*/,
+       size_t /*len*/,
+       heim_ia5_string */*str*/,
+       size_t */*size*/);
+
+int
+der_get_integer (
+       const unsigned char */*p*/,
+       size_t /*len*/,
+       int */*ret*/,
+       size_t */*size*/);
+
+int
+der_get_length (
+       const unsigned char */*p*/,
+       size_t /*len*/,
+       size_t */*val*/,
+       size_t */*size*/);
+
+int
+der_get_octet_string (
+       const unsigned char */*p*/,
+       size_t /*len*/,
+       heim_octet_string */*data*/,
+       size_t */*size*/);
+
+int
+der_get_octet_string_ber (
+       const unsigned char */*p*/,
+       size_t /*len*/,
+       heim_octet_string */*data*/,
+       size_t */*size*/);
+
+int
+der_get_oid (
+       const unsigned char */*p*/,
+       size_t /*len*/,
+       heim_oid */*data*/,
+       size_t */*size*/);
+
+int
+der_get_printable_string (
+       const unsigned char */*p*/,
+       size_t /*len*/,
+       heim_printable_string */*str*/,
+       size_t */*size*/);
+
+int
+der_get_tag (
+       const unsigned char */*p*/,
+       size_t /*len*/,
+       Der_class */*class*/,
+       Der_type */*type*/,
+       unsigned int */*tag*/,
+       size_t */*size*/);
+
+const char *
+der_get_tag_name (unsigned /*num*/);
+
+int
+der_get_tag_num (const char */*name*/);
+
+const char *
+der_get_type_name (unsigned /*num*/);
+
+int
+der_get_type_num (const char */*name*/);
+
+int
+der_get_universal_string (
+       const unsigned char */*p*/,
+       size_t /*len*/,
+       heim_universal_string */*data*/,
+       size_t */*size*/);
+
+int
+der_get_unsigned (
+       const unsigned char */*p*/,
+       size_t /*len*/,
+       unsigned */*ret*/,
+       size_t */*size*/);
+
+int
+der_get_utctime (
+       const unsigned char */*p*/,
+       size_t /*len*/,
+       time_t */*data*/,
+       size_t */*size*/);
+
+int
+der_get_utf8string (
+       const unsigned char */*p*/,
+       size_t /*len*/,
+       heim_utf8_string */*str*/,
+       size_t */*size*/);
+
+int
+der_get_visible_string (
+       const unsigned char */*p*/,
+       size_t /*len*/,
+       heim_visible_string */*str*/,
+       size_t */*size*/);
+
+int
+der_heim_bit_string_cmp (
+       const heim_bit_string */*p*/,
+       const heim_bit_string */*q*/);
+
+int
+der_heim_bmp_string_cmp (
+       const heim_bmp_string */*p*/,
+       const heim_bmp_string */*q*/);
+
+int
+der_heim_integer_cmp (
+       const heim_integer */*p*/,
+       const heim_integer */*q*/);
+
+int
+der_heim_octet_string_cmp (
+       const heim_octet_string */*p*/,
+       const heim_octet_string */*q*/);
+
+int
+der_heim_oid_cmp (
+       const heim_oid */*p*/,
+       const heim_oid */*q*/);
+
+int
+der_heim_universal_string_cmp (
+       const heim_universal_string */*p*/,
+       const heim_universal_string */*q*/);
+
+size_t
+der_length_bit_string (const heim_bit_string */*k*/);
+
+size_t
+der_length_bmp_string (const heim_bmp_string */*data*/);
+
+size_t
+der_length_boolean (const int */*k*/);
+
+size_t
+der_length_enumerated (const unsigned */*data*/);
+
+size_t
+der_length_general_string (const heim_general_string */*data*/);
+
+size_t
+der_length_generalized_time (const time_t */*t*/);
+
+size_t
+der_length_heim_integer (const heim_integer */*k*/);
+
+size_t
+der_length_ia5_string (const heim_ia5_string */*data*/);
+
+size_t
+der_length_integer (const int */*data*/);
+
+size_t
+der_length_len (size_t /*len*/);
+
+size_t
+der_length_octet_string (const heim_octet_string */*k*/);
+
+size_t
+der_length_oid (const heim_oid */*k*/);
+
+size_t
+der_length_printable_string (const heim_printable_string */*data*/);
+
+size_t
+der_length_universal_string (const heim_universal_string */*data*/);
+
+size_t
+der_length_unsigned (const unsigned */*data*/);
+
+size_t
+der_length_utctime (const time_t */*t*/);
+
+size_t
+der_length_utf8string (const heim_utf8_string */*data*/);
+
+size_t
+der_length_visible_string (const heim_visible_string */*data*/);
+
+int
+der_match_tag (
+       const unsigned char */*p*/,
+       size_t /*len*/,
+       Der_class /*class*/,
+       Der_type /*type*/,
+       unsigned int /*tag*/,
+       size_t */*size*/);
+
+int
+der_match_tag2 (
+       const unsigned char */*p*/,
+       size_t /*len*/,
+       Der_class /*class*/,
+       Der_type */*type*/,
+       unsigned int /*tag*/,
+       size_t */*size*/);
+
+int
+der_match_tag_and_length (
+       const unsigned char */*p*/,
+       size_t /*len*/,
+       Der_class /*class*/,
+       Der_type */*type*/,
+       unsigned int /*tag*/,
+       size_t */*length_ret*/,
+       size_t */*size*/);
+
+int
+der_parse_heim_oid (
+       const char */*str*/,
+       const char */*sep*/,
+       heim_oid */*data*/);
+
+int
+der_parse_hex_heim_integer (
+       const char */*p*/,
+       heim_integer */*data*/);
+
+int
+der_print_heim_oid (
+       const heim_oid */*oid*/,
+       char /*delim*/,
+       char **/*str*/);
+
+int
+der_print_hex_heim_integer (
+       const heim_integer */*data*/,
+       char **/*p*/);
+
+int
+der_put_bit_string (
+       unsigned char */*p*/,
+       size_t /*len*/,
+       const heim_bit_string */*data*/,
+       size_t */*size*/);
+
+int
+der_put_bmp_string (
+       unsigned char */*p*/,
+       size_t /*len*/,
+       const heim_bmp_string */*data*/,
+       size_t */*size*/);
+
+int
+der_put_boolean (
+       unsigned char */*p*/,
+       size_t /*len*/,
+       const int */*data*/,
+       size_t */*size*/);
+
+int
+der_put_general_string (
+       unsigned char */*p*/,
+       size_t /*len*/,
+       const heim_general_string */*str*/,
+       size_t */*size*/);
+
+int
+der_put_generalized_time (
+       unsigned char */*p*/,
+       size_t /*len*/,
+       const time_t */*data*/,
+       size_t */*size*/);
+
+int
+der_put_heim_integer (
+       unsigned char */*p*/,
+       size_t /*len*/,
+       const heim_integer */*data*/,
+       size_t */*size*/);
+
+int
+der_put_ia5_string (
+       unsigned char */*p*/,
+       size_t /*len*/,
+       const heim_ia5_string */*str*/,
+       size_t */*size*/);
+
+int
+der_put_integer (
+       unsigned char */*p*/,
+       size_t /*len*/,
+       const int */*v*/,
+       size_t */*size*/);
+
+int
+der_put_length (
+       unsigned char */*p*/,
+       size_t /*len*/,
+       size_t /*val*/,
+       size_t */*size*/);
+
+int
+der_put_length_and_tag (
+       unsigned char */*p*/,
+       size_t /*len*/,
+       size_t /*len_val*/,
+       Der_class /*class*/,
+       Der_type /*type*/,
+       unsigned int /*tag*/,
+       size_t */*size*/);
+
+int
+der_put_octet_string (
+       unsigned char */*p*/,
+       size_t /*len*/,
+       const heim_octet_string */*data*/,
+       size_t */*size*/);
+
+int
+der_put_oid (
+       unsigned char */*p*/,
+       size_t /*len*/,
+       const heim_oid */*data*/,
+       size_t */*size*/);
+
+int
+der_put_printable_string (
+       unsigned char */*p*/,
+       size_t /*len*/,
+       const heim_printable_string */*str*/,
+       size_t */*size*/);
+
+int
+der_put_tag (
+       unsigned char */*p*/,
+       size_t /*len*/,
+       Der_class /*class*/,
+       Der_type /*type*/,
+       unsigned int /*tag*/,
+       size_t */*size*/);
+
+int
+der_put_universal_string (
+       unsigned char */*p*/,
+       size_t /*len*/,
+       const heim_universal_string */*data*/,
+       size_t */*size*/);
+
+int
+der_put_unsigned (
+       unsigned char */*p*/,
+       size_t /*len*/,
+       const unsigned */*v*/,
+       size_t */*size*/);
+
+int
+der_put_utctime (
+       unsigned char */*p*/,
+       size_t /*len*/,
+       const time_t */*data*/,
+       size_t */*size*/);
+
+int
+der_put_utf8string (
+       unsigned char */*p*/,
+       size_t /*len*/,
+       const heim_utf8_string */*str*/,
+       size_t */*size*/);
+
+int
+der_put_visible_string (
+       unsigned char */*p*/,
+       size_t /*len*/,
+       const heim_visible_string */*str*/,
+       size_t */*size*/);
+
+int
+encode_heim_any (
+       unsigned char */*p*/,
+       size_t /*len*/,
+       const heim_any */*data*/,
+       size_t */*size*/);
+
+int
+encode_heim_any_set (
+       unsigned char */*p*/,
+       size_t /*len*/,
+       const heim_any_set */*data*/,
+       size_t */*size*/);
+
+void
+free_heim_any (heim_any */*data*/);
+
+void
+free_heim_any_set (heim_any_set */*data*/);
+
+int
+heim_any_cmp (
+       const heim_any_set */*p*/,
+       const heim_any_set */*q*/);
+
+size_t
+length_heim_any (const heim_any */*data*/);
+
+size_t
+length_heim_any_set (const heim_any */*data*/);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __der_protos_h__ */
index 0dabb9c..b2d74e9 100644 (file)
 /*
- * Copyright (c) 1997 - 2001 Kungliga Tekniska Högskolan
- * (Royal Institute of Technology, Stockholm, Sweden). 
- * All rights reserved. 
+ * Copyright (c) 1997 - 2006 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: 
+ * 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. 
+ * 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. 
+ * 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. 
+ * 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. 
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
  */
 
+#include <stdarg.h>
+
 /* $Id$ */
 
 #ifndef __DER_H__
 #define __DER_H__
 
-#include <time.h>
+typedef enum {
+    ASN1_C_UNIV = 0,
+    ASN1_C_APPL = 1,
+    ASN1_C_CONTEXT = 2,
+    ASN1_C_PRIVATE = 3
+} Der_class;
 
-typedef enum { UNIV = 0, APPL = 1, Der_CONTEXT = 2, PRIVATE = 3 } Der_class;
+typedef enum {PRIM = 0, CONS = 1} Der_type;
 
-typedef enum { PRIM = 0, CONS = 1 } Der_type;
+#define MAKE_TAG(CLASS, TYPE, TAG)  (((CLASS) << 6) | ((TYPE) << 5) | (TAG))
 
 /* Universal tags */
 
 enum {
-    UT_Boolean = 1,
-    UT_Integer = 2,
-    UT_BitString = 3,
-    UT_OctetString = 4,
-    UT_Null = 5,
-    UT_OID = 6,
-    UT_Enumerated = 10,
-    UT_Sequence = 16,
-    UT_Set = 17,
-    UT_PrintableString = 19,
-    UT_IA5String = 22,
-    UT_UTCTime = 23,
-    UT_GeneralizedTime = 24,
-    UT_VisibleString = 26,
-    UT_GeneralString = 27
+    UT_EndOfContent    = 0,
+    UT_Boolean         = 1,
+    UT_Integer         = 2,
+    UT_BitString       = 3,
+    UT_OctetString     = 4,
+    UT_Null            = 5,
+    UT_OID             = 6,
+    UT_Enumerated      = 10,
+    UT_UTF8String      = 12,
+    UT_Sequence                = 16,
+    UT_Set             = 17,
+    UT_PrintableString = 19,
+    UT_IA5String       = 22,
+    UT_UTCTime         = 23,
+    UT_GeneralizedTime = 24,
+    UT_UniversalString = 25,
+    UT_VisibleString   = 26,
+    UT_GeneralString   = 27,
+    UT_BMPString       = 30,
+    /* unsupported types */
+    UT_ObjectDescriptor = 7,
+    UT_External                = 8,
+    UT_Real            = 9,
+    UT_EmbeddedPDV     = 11,
+    UT_RelativeOID     = 13,
+    UT_NumericString   = 18,
+    UT_TeletexString   = 20,
+    UT_VideotexString  = 21,
+    UT_GraphicString   = 25
 };
 
 #define ASN1_INDEFINITE 0xdce0deed
 
-#ifndef HAVE_TIMEGM
-time_t timegm(struct tm *);
-#endif
-
-int time2generalizedtime(time_t t, octet_string * s);
-
-int der_get_int(const unsigned char *p, size_t len, int *ret, size_t * size);
-int der_get_length(const unsigned char *p, size_t len, size_t * val,
-                  size_t * size);
-int der_get_general_string(const unsigned char *p, size_t len,
-                          general_string * str, size_t * size);
-int der_get_octet_string(const unsigned char *p, size_t len,
-                        octet_string * data, size_t * size);
-int der_get_oid(const unsigned char *p, size_t len, oid * data,
-               size_t * size);
-int der_get_tag(const unsigned char *p, size_t len, Der_class * class,
-               Der_type * type, int *tag, size_t * size);
-
-int der_match_tag(const unsigned char *p, size_t len, Der_class class,
-                 Der_type type, int tag, size_t * size);
-int der_match_tag_and_length(const unsigned char *p, size_t len,
-                            Der_class class, Der_type type, int tag,
-                            size_t * length_ret, size_t * size);
-
-int decode_integer(const unsigned char *, size_t, int *, size_t *);
-int decode_unsigned(const unsigned char *, size_t, unsigned *, size_t *);
-int decode_enumerated(const unsigned char *, size_t, unsigned *, size_t *);
-int decode_general_string(const unsigned char *, size_t, general_string *,
-                         size_t *);
-int decode_oid(const unsigned char *p, size_t len, oid * k, size_t * size);
-int decode_octet_string(const unsigned char *, size_t, octet_string *,
-                       size_t *);
-int decode_generalized_time(const unsigned char *, size_t, time_t *,
-                           size_t *);
-
-int der_put_int(unsigned char *p, size_t len, int val, size_t *);
-int der_put_length(unsigned char *p, size_t len, size_t val, size_t *);
-int der_put_general_string(unsigned char *p, size_t len,
-                          const general_string * str, size_t *);
-int der_put_octet_string(unsigned char *p, size_t len,
-                        const octet_string * data, size_t *);
-int der_put_oid(unsigned char *p, size_t len, const oid * data,
-               size_t * size);
-int der_put_tag(unsigned char *p, size_t len, Der_class class, Der_type type,
-               int tag, size_t *);
-int der_put_length_and_tag(unsigned char *, size_t, size_t, Der_class,
-                          Der_type, int, size_t *);
-
-int encode_integer(unsigned char *p, size_t len, const int *data, size_t *);
-int encode_unsigned(unsigned char *p, size_t len, const unsigned *data,
-                   size_t *);
-int encode_enumerated(unsigned char *p, size_t len, const unsigned *data,
-                     size_t *);
-int encode_general_string(unsigned char *p, size_t len,
-                         const general_string * data, size_t *);
-int encode_octet_string(unsigned char *p, size_t len, const octet_string * k,
-                       size_t *);
-int encode_oid(unsigned char *p, size_t len, const oid * k, size_t *);
-int encode_generalized_time(unsigned char *p, size_t len, const time_t * t,
-                           size_t *);
+typedef struct heim_der_time_t {
+    time_t dt_sec;
+    unsigned long dt_nsec;
+} heim_der_time_t;
 
-void free_integer(int *num);
-void free_general_string(general_string * str);
-void free_octet_string(octet_string * k);
-void free_oid(oid * k);
-void free_generalized_time(time_t * t);
+typedef struct heim_ber_time_t {
+    time_t bt_sec;
+    unsigned bt_nsec;
+    int bt_zone;
+} heim_ber_time_t;
 
-size_t length_len(size_t len);
-size_t length_integer(const int *data);
-size_t length_unsigned(const unsigned *data);
-size_t length_enumerated(const unsigned *data);
-size_t length_general_string(const general_string * data);
-size_t length_octet_string(const octet_string * k);
-size_t length_oid(const oid * k);
-size_t length_generalized_time(const time_t * t);
+struct asn1_template;
 
-int copy_general_string(const general_string * from, general_string * to);
-int copy_octet_string(const octet_string * from, octet_string * to);
-int copy_oid(const oid * from, oid * to);
+#include <der-protos.h>
 
-int fix_dce(size_t reallen, size_t * len);
+int _heim_fix_dce(size_t reallen, size_t *len);
+int _heim_der_set_sort(const void *, const void *);
+int _heim_time2generalizedtime (time_t, heim_octet_string *, int);
 
 #endif /* __DER_H__ */
index 3dea140..daf0e76 100644 (file)
@@ -75,9 +75,8 @@
 #include "rxkad.h"
 
 #include "v5gen-rewrite.h"
-#include "asn1-common.h"
-#include "der.h"
 #include "v5gen.h"
+#include "der.h"
 #include "v5der.c"
 #include "v5gen.c"
 #include "md4.h"
index 7b7e67b..fc9cdb4 100644 (file)
 #include "asn1_err.h"
 #include <errno.h>
 /*
- * Copyright (c) 1997 - 2002 Kungliga Tekniska Högskolan
- * (Royal Institute of Technology, Stockholm, Sweden). 
- * All rights reserved. 
+ * Copyright (c) 1997 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: 
+ * 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. 
+ * 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. 
+ * 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. 
+ * 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. 
+ * 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.
  */
 
 
-/* RCSID("Heimdal: der_get.c,v 1.33 2002/09/03 16:21:49 nectar Exp $"); */
+/* RCSID("$Id$"); */
 
+static int
+is_leap(unsigned y)
+{
+    y += 1900;
+    return (y % 4) == 0 && ((y % 100) != 0 || (y % 400) == 0);
+}
+
+/*
+ * This is a simplifed version of timegm(3) that doesn't accept out of
+ * bound values that timegm(3) normally accepts but those are not
+ * valid in asn1 encodings.
+ */
+
+time_t
+_der_timegm (struct tm *tm)
+{
+  static const unsigned ndays[2][12] ={
+    {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
+    {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}};
+  time_t res = 0;
+  unsigned i;
+
+  if (tm->tm_year < 0)
+      return -1;
+  if (tm->tm_mon < 0 || tm->tm_mon > 11)
+      return -1;
+  if (tm->tm_mday < 1 || tm->tm_mday > ndays[is_leap(tm->tm_year)][tm->tm_mon])
+      return -1;
+  if (tm->tm_hour < 0 || tm->tm_hour > 23)
+      return -1;
+  if (tm->tm_min < 0 || tm->tm_min > 59)
+      return -1;
+  if (tm->tm_sec < 0 || tm->tm_sec > 59)
+      return -1;
+
+  for (i = 70; i < tm->tm_year; ++i)
+    res += is_leap(i) ? 366 : 365;
+
+  for (i = 0; i < tm->tm_mon; ++i)
+    res += ndays[is_leap(tm->tm_year)][i];
+  res += tm->tm_mday - 1;
+  res *= 24;
+  res += tm->tm_hour;
+  res *= 60;
+  res += tm->tm_min;
+  res *= 60;
+  res += tm->tm_sec;
+  return res;
+}
+/*
+ * Copyright (c) 1997 - 2007 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.
+ */
 
-/* 
+
+/*
  * All decoding functions take a pointer `p' to first position in
  * which to read, from the left, `len' which means the maximum number
  * of characters we are able to read, `ret' were the value will be
  * Either 0 or an error code is returned.
  */
 
-static int
-der_get_unsigned(const unsigned char *p, size_t len, unsigned *ret,
-                size_t * size)
+int
+der_get_unsigned (const unsigned char *p, size_t len,
+                 unsigned *ret, size_t *size)
 {
     unsigned val = 0;
     size_t oldlen = len;
 
+    if (len == sizeof(unsigned) + 1 && p[0] == 0)
+       ;
+    else if (len > sizeof(unsigned))
+       return ASN1_OVERRUN;
+
     while (len--)
        val = val * 256 + *p++;
     *ret = val;
-    if (size)
-       *size = oldlen;
+    if(size) *size = oldlen;
     return 0;
 }
 
 int
-der_get_int(const unsigned char *p, size_t len, int *ret, size_t * size)
+der_get_integer (const unsigned char *p, size_t len,
+                int *ret, size_t *size)
 {
     int val = 0;
     size_t oldlen = len;
 
+    if (len > sizeof(int))
+       return ASN1_OVERRUN;
+
     if (len > 0) {
        val = (signed char)*p++;
        while (--len)
            val = val * 256 + *p++;
     }
     *ret = val;
-    if (size)
-       *size = oldlen;
+    if(size) *size = oldlen;
     return 0;
 }
 
 int
-der_get_length(const unsigned char *p, size_t len, size_t * val,
-              size_t * size)
+der_get_length (const unsigned char *p, size_t len,
+               size_t *val, size_t *size)
 {
     size_t v;
 
@@ -89,469 +178,587 @@ der_get_length(const unsigned char *p, size_t len, size_t * val,
     v = *p++;
     if (v < 128) {
        *val = v;
-       if (size)
-           *size = 1;
+       if(size) *size = 1;
     } else {
        int e;
        size_t l;
        unsigned tmp;
 
-       if (v == 0x80) {
+       if(v == 0x80){
            *val = ASN1_INDEFINITE;
-           if (size)
-               *size = 1;
+           if(size) *size = 1;
            return 0;
        }
        v &= 0x7F;
        if (len < v)
            return ASN1_OVERRUN;
-       e = der_get_unsigned(p, v, &tmp, &l);
-       if (e)
-           return e;
+       e = der_get_unsigned (p, v, &tmp, &l);
+       if(e) return e;
        *val = tmp;
-       if (size)
-           *size = l + 1;
+       if(size) *size = l + 1;
     }
     return 0;
 }
 
 int
-der_get_general_string(const unsigned char *p, size_t len,
-                      general_string * str, size_t * size)
+der_get_boolean(const unsigned char *p, size_t len, int *data, size_t *size)
+{
+    if(len < 1)
+       return ASN1_OVERRUN;
+    if(*p != 0)
+       *data = 1;
+    else
+       *data = 0;
+    *size = 1;
+    return 0;
+}
+
+int
+der_get_general_string (const unsigned char *p, size_t len,
+                       heim_general_string *str, size_t *size)
 {
+    const unsigned char *p1;
     char *s;
 
-    s = malloc(len + 1);
+    p1 = memchr(p, 0, len);
+    if (p1 != NULL) {
+       /*
+        * Allow trailing NULs. We allow this since MIT Kerberos sends
+        * an strings in the NEED_PREAUTH case that includes a
+        * trailing NUL.
+        */
+       while (p1 - p < len && *p1 == '\0')
+           p1++;
+       if (p1 - p != len)
+           return ASN1_BAD_CHARACTER;
+    }
+    if (len > len + 1)
+       return ASN1_BAD_LENGTH;
+
+    s = malloc (len + 1);
     if (s == NULL)
        return ENOMEM;
-    memcpy(s, p, len);
+    memcpy (s, p, len);
     s[len] = '\0';
     *str = s;
-    if (size)
-       *size = len;
+    if(size) *size = len;
     return 0;
 }
 
 int
-der_get_octet_string(const unsigned char *p, size_t len, octet_string * data,
-                    size_t * size)
+der_get_utf8string (const unsigned char *p, size_t len,
+                   heim_utf8_string *str, size_t *size)
 {
-    data->length = len;
-    data->data = malloc(len);
-    if (data->data == NULL && data->length != 0)
-       return ENOMEM;
-    memcpy(data->data, p, len);
-    if (size)
-       *size = len;
-    return 0;
+    return der_get_general_string(p, len, str, size);
 }
 
 int
-der_get_oid(const unsigned char *p, size_t len, oid * data, size_t * size)
+der_get_printable_string (const unsigned char *p, size_t len,
+                         heim_printable_string *str, size_t *size)
 {
-    int n;
-    size_t oldlen = len;
+    return der_get_general_string(p, len, str, size);
+}
 
-    if (len < 1)
-       return ASN1_OVERRUN;
+int
+der_get_ia5_string (const unsigned char *p, size_t len,
+                   heim_ia5_string *str, size_t *size)
+{
+    return der_get_general_string(p, len, str, size);
+}
 
-    data->components = malloc(len * sizeof(*data->components));
-    if (data->components == NULL && len != 0)
+int
+der_get_bmp_string (const unsigned char *p, size_t len,
+                   heim_bmp_string *data, size_t *size)
+{
+    size_t i;
+
+    if (len & 1)
+       return ASN1_BAD_FORMAT;
+    data->length = len / 2;
+    if (data->length > UINT_MAX/sizeof(data->data[0]))
+       return ERANGE;
+    data->data = malloc(data->length * sizeof(data->data[0]));
+    if (data->data == NULL && data->length != 0)
        return ENOMEM;
-    data->components[0] = (*p) / 40;
-    data->components[1] = (*p) % 40;
-    --len;
-    ++p;
-    for (n = 2; len > 0; ++n) {
-       unsigned u = 0;
 
-       do {
-           --len;
-           u = u * 128 + (*p++ % 128);
-       } while (len > 0 && p[-1] & 0x80);
-       data->components[n] = u;
-    }
-    if (p[-1] & 0x80) {
-       free_oid(data);
-       return ASN1_OVERRUN;
+    for (i = 0; i < data->length; i++) {
+       data->data[i] = (p[0] << 8) | p[1];
+       p += 2;
+       /* check for NUL in the middle of the string */
+       if (data->data[i] == 0 && i != (data->length - 1)) {
+           free(data->data);
+           data->data = NULL;
+           data->length = 0;
+           return ASN1_BAD_CHARACTER;
+       }
     }
-    data->length = n;
-    if (size)
-       *size = oldlen;
+    if (size) *size = len;
+
     return 0;
 }
 
 int
-der_get_tag(const unsigned char *p, size_t len, Der_class * class,
-           Der_type * type, int *tag, size_t * size)
+der_get_universal_string (const unsigned char *p, size_t len,
+                         heim_universal_string *data, size_t *size)
 {
-    if (len < 1)
-       return ASN1_OVERRUN;
-    *class = (Der_class) (((*p) >> 6) & 0x03);
-    *type = (Der_type) (((*p) >> 5) & 0x01);
-    *tag = (*p) & 0x1F;
-    if (size)
-       *size = 1;
+    size_t i;
+
+    if (len & 3)
+       return ASN1_BAD_FORMAT;
+    data->length = len / 4;
+    if (data->length > UINT_MAX/sizeof(data->data[0]))
+       return ERANGE;
+    data->data = malloc(data->length * sizeof(data->data[0]));
+    if (data->data == NULL && data->length != 0)
+       return ENOMEM;
+
+    for (i = 0; i < data->length; i++) {
+       data->data[i] = (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3];
+       p += 4;
+       /* check for NUL in the middle of the string */
+       if (data->data[i] == 0 && i != (data->length - 1)) {
+           free(data->data);
+           data->data = NULL;
+           data->length = 0;
+           return ASN1_BAD_CHARACTER;
+       }
+    }
+    if (size) *size = len;
     return 0;
 }
 
 int
-der_match_tag(const unsigned char *p, size_t len, Der_class class,
-             Der_type type, int tag, size_t * size)
+der_get_visible_string (const unsigned char *p, size_t len,
+                       heim_visible_string *str, size_t *size)
 {
-    size_t l;
-    Der_class thisclass;
-    Der_type thistype;
-    int thistag;
-    int e;
-
-    e = der_get_tag(p, len, &thisclass, &thistype, &thistag, &l);
-    if (e)
-       return e;
-    if (class != thisclass || type != thistype)
-       return ASN1_BAD_ID;
-    if (tag > thistag)
-       return ASN1_MISPLACED_FIELD;
-    if (tag < thistag)
-       return ASN1_MISSING_FIELD;
-    if (size)
-       *size = l;
-    return 0;
+    return der_get_general_string(p, len, str, size);
 }
 
 int
-der_match_tag_and_length(const unsigned char *p, size_t len, Der_class class,
-                        Der_type type, int tag, size_t * length_ret,
-                        size_t * size)
+der_get_octet_string (const unsigned char *p, size_t len,
+                     heim_octet_string *data, size_t *size)
 {
-    size_t l, ret = 0;
-    int e;
-
-    e = der_match_tag(p, len, class, type, tag, &l);
-    if (e)
-       return e;
-    p += l;
-    len -= l;
-    ret += l;
-    e = der_get_length(p, len, length_ret, &l);
-    if (e)
-       return e;
-    p += l;
-    len -= l;
-    ret += l;
-    if (size)
-       *size = ret;
+    data->length = len;
+    data->data = malloc(len);
+    if (data->data == NULL && data->length != 0)
+       return ENOMEM;
+    memcpy (data->data, p, len);
+    if(size) *size = len;
     return 0;
 }
 
 int
-decode_integer(const unsigned char *p, size_t len, int *num, size_t * size)
+der_get_octet_string_ber (const unsigned char *p, size_t len,
+                         heim_octet_string *data, size_t *size)
 {
-    size_t ret = 0;
-    size_t l, reallen;
     int e;
+    Der_type type;
+    Der_class class;
+    unsigned int tag, depth = 0;
+    size_t l, datalen, oldlen = len;
+
+    data->length = 0;
+    data->data = NULL;
+
+    while (len) {
+       e = der_get_tag (p, len, &class, &type, &tag, &l);
+       if (e) goto out;
+       if (class != ASN1_C_UNIV) {
+           e = ASN1_BAD_ID;
+           goto out;
+       }
+       if (type == PRIM && tag == UT_EndOfContent) {
+           if (depth == 0)
+               break;
+           depth--;
+       }
+       if (tag != UT_OctetString) {
+           e = ASN1_BAD_ID;
+           goto out;
+       }
 
-    e = der_match_tag(p, len, UNIV, PRIM, UT_Integer, &l);
-    if (e)
-       return e;
-    p += l;
-    len -= l;
-    ret += l;
-    e = der_get_length(p, len, &reallen, &l);
-    if (e)
-       return e;
-    p += l;
-    len -= l;
-    ret += l;
-    if (reallen > len)
-       return ASN1_OVERRUN;
-    e = der_get_int(p, reallen, num, &l);
-    if (e)
-       return e;
-    p += l;
-    len -= l;
-    ret += l;
-    if (size)
-       *size = ret;
+       p += l;
+       len -= l;
+       e = der_get_length (p, len, &datalen, &l);
+       if (e) goto out;
+       p += l;
+       len -= l;
+
+       if (datalen > len)
+           return ASN1_OVERRUN;
+
+       if (type == PRIM) {
+           void *ptr;
+
+           ptr = realloc(data->data, data->length + datalen);
+           if (ptr == NULL) {
+               e = ENOMEM;
+               goto out;
+           }
+           data->data = ptr;
+           memcpy(((unsigned char *)data->data) + data->length, p, datalen);
+           data->length += datalen;
+       } else
+           depth++;
+
+       p += datalen;
+       len -= datalen;
+    }
+    if (depth != 0)
+       return ASN1_INDEF_OVERRUN;
+    if(size) *size = oldlen - len;
     return 0;
+ out:
+    free(data->data);
+    data->data = NULL;
+    data->length = 0;
+    return e;
 }
 
+
 int
-decode_unsigned(const unsigned char *p, size_t len, unsigned *num,
-               size_t * size)
+der_get_heim_integer (const unsigned char *p, size_t len,
+                     heim_integer *data, size_t *size)
 {
-    size_t ret = 0;
-    size_t l, reallen;
-    int e;
+    data->length = 0;
+    data->negative = 0;
+    data->data = NULL;
 
-    e = der_match_tag(p, len, UNIV, PRIM, UT_Integer, &l);
-    if (e)
-       return e;
-    p += l;
-    len -= l;
-    ret += l;
-    e = der_get_length(p, len, &reallen, &l);
-    if (e)
-       return e;
-    p += l;
-    len -= l;
-    ret += l;
-    if (reallen > len)
-       return ASN1_OVERRUN;
-    e = der_get_unsigned(p, reallen, num, &l);
-    if (e)
-       return e;
-    p += l;
-    len -= l;
-    ret += l;
+    if (len == 0) {
+       if (size)
+           *size = 0;
+       return 0;
+    }
+    if (p[0] & 0x80) {
+       unsigned char *q;
+       int carry = 1;
+       data->negative = 1;
+
+       data->length = len;
+
+       if (p[0] == 0xff) {
+           p++;
+           data->length--;
+       }
+       data->data = malloc(data->length);
+       if (data->data == NULL) {
+           data->length = 0;
+           if (size)
+               *size = 0;
+           return ENOMEM;
+       }
+       q = &((unsigned char*)data->data)[data->length - 1];
+       p += data->length - 1;
+       while (q >= (unsigned char*)data->data) {
+           *q = *p ^ 0xff;
+           if (carry)
+               carry = !++*q;
+           p--;
+           q--;
+       }
+    } else {
+       data->negative = 0;
+       data->length = len;
+
+       if (p[0] == 0) {
+           p++;
+           data->length--;
+       }
+       data->data = malloc(data->length);
+       if (data->data == NULL && data->length != 0) {
+           data->length = 0;
+           if (size)
+               *size = 0;
+           return ENOMEM;
+       }
+       memcpy(data->data, p, data->length);
+    }
     if (size)
-       *size = ret;
+       *size = len;
     return 0;
 }
 
-int
-decode_enumerated(const unsigned char *p, size_t len, unsigned *num,
-                 size_t * size)
+static int
+generalizedtime2time (const char *s, time_t *t)
 {
-    size_t ret = 0;
-    size_t l, reallen;
-    int e;
+    struct tm tm;
 
-    e = der_match_tag(p, len, UNIV, PRIM, UT_Enumerated, &l);
-    if (e)
-       return e;
-    p += l;
-    len -= l;
-    ret += l;
-    e = der_get_length(p, len, &reallen, &l);
-    if (e)
-       return e;
-    p += l;
-    len -= l;
-    ret += l;
-    e = der_get_unsigned(p, reallen, num, &l);
-    if (e)
-       return e;
-    p += l;
-    len -= l;
-    ret += l;
-    if (size)
-       *size = ret;
+    memset(&tm, 0, sizeof(tm));
+    if (sscanf (s, "%04d%02d%02d%02d%02d%02dZ",
+               &tm.tm_year, &tm.tm_mon, &tm.tm_mday, &tm.tm_hour,
+               &tm.tm_min, &tm.tm_sec) != 6) {
+       if (sscanf (s, "%02d%02d%02d%02d%02d%02dZ",
+                   &tm.tm_year, &tm.tm_mon, &tm.tm_mday, &tm.tm_hour,
+                   &tm.tm_min, &tm.tm_sec) != 6)
+           return ASN1_BAD_TIMEFORMAT;
+       if (tm.tm_year < 50)
+           tm.tm_year += 2000;
+       else
+           tm.tm_year += 1900;
+    }
+    tm.tm_year -= 1900;
+    tm.tm_mon -= 1;
+    *t = _der_timegm (&tm);
     return 0;
 }
 
-int
-decode_general_string(const unsigned char *p, size_t len,
-                     general_string * str, size_t * size)
+static int
+der_get_time (const unsigned char *p, size_t len,
+             time_t *data, size_t *size)
 {
-    size_t ret = 0;
-    size_t l;
+    char *times;
     int e;
-    size_t slen;
 
-    e = der_match_tag(p, len, UNIV, PRIM, UT_GeneralString, &l);
-    if (e)
-       return e;
-    p += l;
-    len -= l;
-    ret += l;
+    if (len > len + 1 || len == 0)
+       return ASN1_BAD_LENGTH;
 
-    e = der_get_length(p, len, &slen, &l);
-    if (e)
-       return e;
-    p += l;
-    len -= l;
-    ret += l;
-    if (len < slen)
-       return ASN1_OVERRUN;
+    times = malloc(len + 1);
+    if (times == NULL)
+       return ENOMEM;
+    memcpy(times, p, len);
+    times[len] = '\0';
+    e = generalizedtime2time(times, data);
+    free (times);
+    if(size) *size = len;
+    return e;
+}
 
-    e = der_get_general_string(p, slen, str, &l);
-    if (e)
-       return e;
-    p += l;
-    len -= l;
-    ret += l;
-    if (size)
-       *size = ret;
-    return 0;
+int
+der_get_generalized_time (const unsigned char *p, size_t len,
+                         time_t *data, size_t *size)
+{
+    return der_get_time(p, len, data, size);
 }
 
 int
-decode_octet_string(const unsigned char *p, size_t len, octet_string * k,
-                   size_t * size)
+der_get_utctime (const unsigned char *p, size_t len,
+                         time_t *data, size_t *size)
 {
-    size_t ret = 0;
-    size_t l;
-    int e;
-    size_t slen;
+    return der_get_time(p, len, data, size);
+}
 
-    e = der_match_tag(p, len, UNIV, PRIM, UT_OctetString, &l);
-    if (e)
-       return e;
-    p += l;
-    len -= l;
-    ret += l;
+int
+der_get_oid (const unsigned char *p, size_t len,
+            heim_oid *data, size_t *size)
+{
+    size_t n;
+    size_t oldlen = len;
 
-    e = der_get_length(p, len, &slen, &l);
-    if (e)
-       return e;
-    p += l;
-    len -= l;
-    ret += l;
-    if (len < slen)
+    if (len < 1)
        return ASN1_OVERRUN;
 
-    e = der_get_octet_string(p, slen, k, &l);
-    if (e)
-       return e;
-    p += l;
-    len -= l;
-    ret += l;
+    if (len > len + 1)
+       return ASN1_BAD_LENGTH;
+
+    if (len + 1 > UINT_MAX/sizeof(data->components[0]))
+       return ERANGE;
+
+    data->components = malloc((len + 1) * sizeof(data->components[0]));
+    if (data->components == NULL)
+       return ENOMEM;
+    data->components[0] = (*p) / 40;
+    data->components[1] = (*p) % 40;
+    --len;
+    ++p;
+    for (n = 2; len > 0; ++n) {
+       unsigned u = 0, u1;
+
+       do {
+           --len;
+           u1 = u * 128 + (*p++ % 128);
+           /* check that we don't overflow the element */
+           if (u1 < u) {
+               der_free_oid(data);
+               return ASN1_OVERRUN;
+           }
+           u = u1;
+       } while (len > 0 && p[-1] & 0x80);
+       data->components[n] = u;
+    }
+    if (n > 2 && p[-1] & 0x80) {
+       der_free_oid (data);
+       return ASN1_OVERRUN;
+    }
+    data->length = n;
     if (size)
-       *size = ret;
+       *size = oldlen;
     return 0;
 }
 
 int
-decode_oid(const unsigned char *p, size_t len, oid * k, size_t * size)
+der_get_tag (const unsigned char *p, size_t len,
+            Der_class *class, Der_type *type,
+            unsigned int *tag, size_t *size)
 {
     size_t ret = 0;
-    size_t l;
-    int e;
-    size_t slen;
-
-    e = der_match_tag(p, len, UNIV, PRIM, UT_OID, &l);
-    if (e)
-       return e;
-    p += l;
-    len -= l;
-    ret += l;
-
-    e = der_get_length(p, len, &slen, &l);
-    if (e)
-       return e;
-    p += l;
-    len -= l;
-    ret += l;
-    if (len < slen)
+    if (len < 1)
        return ASN1_OVERRUN;
-
-    e = der_get_oid(p, slen, k, &l);
-    if (e)
-       return e;
-    p += l;
-    len -= l;
-    ret += l;
-    if (size)
-       *size = ret;
+    *class = (Der_class)(((*p) >> 6) & 0x03);
+    *type = (Der_type)(((*p) >> 5) & 0x01);
+    *tag = (*p) & 0x1f;
+    p++; len--; ret++;
+    if(*tag == 0x1f) {
+       unsigned int continuation;
+       unsigned int tag1;
+       *tag = 0;
+       do {
+           if(len < 1)
+               return ASN1_OVERRUN;
+           continuation = *p & 128;
+           tag1 = *tag * 128 + (*p % 128);
+           /* check that we don't overflow the tag */
+           if (tag1 < *tag)
+               return ASN1_OVERFLOW;
+           *tag = tag1;
+           p++; len--; ret++;
+       } while(continuation);
+    }
+    if(size) *size = ret;
     return 0;
 }
 
-static void
-generalizedtime2time(const char *s, time_t * t)
+int
+der_match_tag (const unsigned char *p, size_t len,
+              Der_class class, Der_type type,
+              unsigned int tag, size_t *size)
 {
-    struct tm tm;
+    Der_type thistype;
+    int e;
 
-    memset(&tm, 0, sizeof(tm));
-    sscanf(s, "%04d%02d%02d%02d%02d%02dZ", &tm.tm_year, &tm.tm_mon,
-          &tm.tm_mday, &tm.tm_hour, &tm.tm_min, &tm.tm_sec);
-    tm.tm_year -= 1900;
-    tm.tm_mon -= 1;
-    *t = timegm(&tm);
+    e = der_match_tag2(p, len, class, &thistype, tag, size);
+    if (e) return e;
+    if (thistype != type) return ASN1_BAD_ID;
+    return 0;
 }
 
 int
-decode_generalized_time(const unsigned char *p, size_t len, time_t * t,
-                       size_t * size)
+der_match_tag2 (const unsigned char *p, size_t len,
+               Der_class class, Der_type *type,
+               unsigned int tag, size_t *size)
 {
-    octet_string k;
-    char *times;
-    size_t ret = 0;
     size_t l;
+    Der_class thisclass;
+    unsigned int thistag;
     int e;
-    size_t slen;
 
-    e = der_match_tag(p, len, UNIV, PRIM, UT_GeneralizedTime, &l);
-    if (e)
-       return e;
-    p += l;
-    len -= l;
-    ret += l;
+    e = der_get_tag (p, len, &thisclass, type, &thistag, &l);
+    if (e) return e;
+    if (class != thisclass)
+       return ASN1_BAD_ID;
+    if(tag > thistag)
+       return ASN1_MISPLACED_FIELD;
+    if(tag < thistag)
+       return ASN1_MISSING_FIELD;
+    if(size) *size = l;
+    return 0;
+}
 
-    e = der_get_length(p, len, &slen, &l);
-    if (e)
-       return e;
-    p += l;
-    len -= l;
-    ret += l;
-    if (len < slen)
-       return ASN1_OVERRUN;
-    e = der_get_octet_string(p, slen, &k, &l);
-    if (e)
-       return e;
+int
+der_match_tag_and_length (const unsigned char *p, size_t len,
+                         Der_class class, Der_type *type, unsigned int tag,
+                         size_t *length_ret, size_t *size)
+{
+    size_t l, ret = 0;
+    int e;
+
+    e = der_match_tag2 (p, len, class, type, tag, &l);
+    if (e) return e;
     p += l;
     len -= l;
     ret += l;
-    times = realloc(k.data, k.length + 1);
-    if (times == NULL) {
-       free(k.data);
-       return ENOMEM;
-    }
-    times[k.length] = 0;
-    generalizedtime2time(times, t);
-    free(times);
-    if (size)
-       *size = ret;
+    e = der_get_length (p, len, length_ret, &l);
+    if (e) return e;
+    if(size) *size = ret + l;
     return 0;
 }
 
 
+
+/*
+ * Old versions of DCE was based on a very early beta of the MIT code,
+ * which used MAVROS for ASN.1 encoding. MAVROS had the interesting
+ * feature that it encoded data in the forward direction, which has
+ * it's problems, since you have no idea how long the data will be
+ * until after you're done. MAVROS solved this by reserving one byte
+ * for length, and later, if the actual length was longer, it reverted
+ * to indefinite, BER style, lengths. The version of MAVROS used by
+ * the DCE people could apparently generate correct X.509 DER encodings, and
+ * did this by making space for the length after encoding, but
+ * unfortunately this feature wasn't used with Kerberos.
+ */
+
 int
-fix_dce(size_t reallen, size_t * len)
+_heim_fix_dce(size_t reallen, size_t *len)
 {
-    if (reallen == ASN1_INDEFINITE)
+    if(reallen == ASN1_INDEFINITE)
        return 1;
-    if (*len < reallen)
+    if(*len < reallen)
        return -1;
     *len = reallen;
     return 0;
 }
 
+int
+der_get_bit_string (const unsigned char *p, size_t len,
+                   heim_bit_string *data, size_t *size)
+{
+    if (len < 1)
+       return ASN1_OVERRUN;
+    if (p[0] > 7)
+       return ASN1_BAD_FORMAT;
+    if (len - 1 == 0 && p[0] != 0)
+       return ASN1_BAD_FORMAT;
+    /* check if any of the three upper bits are set
+     * any of them will cause a interger overrun */
+    if ((len - 1) >> (sizeof(len) * 8 - 3))
+       return ASN1_OVERRUN;
+    data->length = (len - 1) * 8;
+    data->data = malloc(len - 1);
+    if (data->data == NULL && (len - 1) != 0)
+       return ENOMEM;
+    /* copy data is there is data to copy */
+    if (len - 1 != 0) {
+      memcpy (data->data, p + 1, len - 1);
+      data->length -= p[0];
+    }
+    if(size) *size = len;
+    return 0;
+}
 /*
- * Copyright (c) 1997 - 2001 Kungliga Tekniska Högskolan
- * (Royal Institute of Technology, Stockholm, Sweden). 
- * All rights reserved. 
+ * Copyright (c) 1997-2005 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: 
+ * 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. 
+ * 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. 
+ * 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. 
+ * 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. 
+ * 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.
  */
 
 
-/* RCSID("Heimdal: der_put.c,v 1.27 2001/09/25 23:37:25 assar Exp $"); */
+/* RCSID("$Id$"); */
 
 /*
  * All encoding functions take a pointer `p' to first position in
@@ -561,10 +768,11 @@ fix_dce(size_t reallen, size_t * len)
  * The return value is 0 or an error.
  */
 
-static int
-der_put_unsigned(unsigned char *p, size_t len, unsigned val, size_t * size)
+int
+der_put_unsigned (unsigned char *p, size_t len, const unsigned *v, size_t *size)
 {
     unsigned char *base = p;
+    unsigned val = *v;
 
     if (val) {
        while (len > 0 && val) {
@@ -575,33 +783,39 @@ der_put_unsigned(unsigned char *p, size_t len, unsigned val, size_t * size)
        if (val != 0)
            return ASN1_OVERFLOW;
        else {
+           if(p[1] >= 128) {
+               if(len < 1)
+                   return ASN1_OVERFLOW;
+               *p-- = 0;
+           }
            *size = base - p;
            return 0;
        }
     } else if (len < 1)
        return ASN1_OVERFLOW;
     else {
-       *p = 0;
+       *p    = 0;
        *size = 1;
        return 0;
     }
 }
 
 int
-der_put_int(unsigned char *p, size_t len, int val, size_t * size)
+der_put_integer (unsigned char *p, size_t len, const int *v, size_t *size)
 {
     unsigned char *base = p;
+    int val = *v;
 
-    if (val >= 0) {
+    if(val >= 0) {
        do {
-           if (len < 1)
+           if(len < 1)
                return ASN1_OVERFLOW;
            *p-- = val % 256;
            len--;
            val /= 256;
-       } while (val);
-       if (p[1] >= 128) {
-           if (len < 1)
+       } while(val);
+       if(p[1] >= 128) {
+           if(len < 1)
                return ASN1_OVERFLOW;
            *p-- = 0;
            len--;
@@ -609,14 +823,14 @@ der_put_int(unsigned char *p, size_t len, int val, size_t * size)
     } else {
        val = ~val;
        do {
-           if (len < 1)
+           if(len < 1)
                return ASN1_OVERFLOW;
            *p-- = ~(val % 256);
            len--;
            val /= 256;
-       } while (val);
-       if (p[1] < 128) {
-           if (len < 1)
+       } while(val);
+       if(p[1] < 128) {
+           if(len < 1)
                return ASN1_OVERFLOW;
            *p-- = 0xff;
            len--;
@@ -628,434 +842,595 @@ der_put_int(unsigned char *p, size_t len, int val, size_t * size)
 
 
 int
-der_put_length(unsigned char *p, size_t len, size_t val, size_t * size)
+der_put_length (unsigned char *p, size_t len, size_t val, size_t *size)
 {
     if (len < 1)
        return ASN1_OVERFLOW;
+
     if (val < 128) {
        *p = val;
        *size = 1;
-       return 0;
     } else {
-       size_t l;
-       int e;
+       size_t l = 0;
 
-       e = der_put_unsigned(p, len - 1, val, &l);
-       if (e)
-           return e;
-       p -= l;
+       while(val > 0) {
+           if(len < 2)
+               return ASN1_OVERFLOW;
+           *p-- = val % 256;
+           val /= 256;
+           len--;
+           l++;
+       }
        *p = 0x80 | l;
-       *size = l + 1;
-       return 0;
+       if(size)
+           *size = l + 1;
     }
+    return 0;
 }
 
 int
-der_put_general_string(unsigned char *p, size_t len,
-                      const general_string * str, size_t * size)
+der_put_boolean(unsigned char *p, size_t len, const int *data, size_t *size)
+{
+    if(len < 1)
+       return ASN1_OVERFLOW;
+    if(*data != 0)
+       *p = 0xff;
+    else
+       *p = 0;
+    *size = 1;
+    return 0;
+}
+
+int
+der_put_general_string (unsigned char *p, size_t len,
+                       const heim_general_string *str, size_t *size)
 {
     size_t slen = strlen(*str);
 
     if (len < slen)
        return ASN1_OVERFLOW;
     p -= slen;
-    len -= slen;
-    memcpy(p + 1, *str, slen);
+    memcpy (p+1, *str, slen);
     *size = slen;
     return 0;
 }
 
 int
-der_put_octet_string(unsigned char *p, size_t len, const octet_string * data,
-                    size_t * size)
+der_put_utf8string (unsigned char *p, size_t len,
+                   const heim_utf8_string *str, size_t *size)
 {
-    if (len < data->length)
-       return ASN1_OVERFLOW;
-    p -= data->length;
-    len -= data->length;
-    memcpy(p + 1, data->data, data->length);
-    *size = data->length;
-    return 0;
+    return der_put_general_string(p, len, str, size);
 }
 
 int
-der_put_oid(unsigned char *p, size_t len, const oid * data, size_t * size)
+der_put_printable_string (unsigned char *p, size_t len,
+                         const heim_printable_string *str, size_t *size)
 {
-    unsigned char *base = p;
-    int n;
+    return der_put_general_string(p, len, str, size);
+}
 
-    for (n = data->length - 1; n >= 2; --n) {
-       unsigned u = data->components[n];
+int
+der_put_ia5_string (unsigned char *p, size_t len,
+                   const heim_ia5_string *str, size_t *size)
+{
+    return der_put_general_string(p, len, str, size);
+}
 
-       if (len < 1)
-           return ASN1_OVERFLOW;
-       *p-- = u % 128;
-       u /= 128;
-       --len;
-       while (u > 0) {
-           if (len < 1)
-               return ASN1_OVERFLOW;
-           *p-- = 128 + u % 128;
-           u /= 128;
-           --len;
-       }
-    }
-    if (len < 1)
+int
+der_put_bmp_string (unsigned char *p, size_t len,
+                   const heim_bmp_string *data, size_t *size)
+{
+    size_t i;
+    if (len / 2 < data->length)
        return ASN1_OVERFLOW;
-    *p-- = 40 * data->components[0] + data->components[1];
-    *size = base - p;
+    p -= data->length * 2;
+    for (i = 0; i < data->length; i++) {
+       p[1] = (data->data[i] >> 8) & 0xff;
+       p[2] = data->data[i] & 0xff;
+       p += 2;
+    }
+    if (size) *size = data->length * 2;
     return 0;
 }
 
 int
-der_put_tag(unsigned char *p, size_t len, Der_class class, Der_type type,
-           int tag, size_t * size)
+der_put_universal_string (unsigned char *p, size_t len,
+                         const heim_universal_string *data, size_t *size)
 {
-    if (len < 1)
+    size_t i;
+    if (len / 4 < data->length)
        return ASN1_OVERFLOW;
-    *p = (class << 6) | (type << 5) | tag;     /* XXX */
-    *size = 1;
+    p -= data->length * 4;
+    for (i = 0; i < data->length; i++) {
+       p[1] = (data->data[i] >> 24) & 0xff;
+       p[2] = (data->data[i] >> 16) & 0xff;
+       p[3] = (data->data[i] >> 8) & 0xff;
+       p[4] = data->data[i] & 0xff;
+       p += 4;
+    }
+    if (size) *size = data->length * 4;
     return 0;
 }
 
 int
-der_put_length_and_tag(unsigned char *p, size_t len, size_t len_val,
-                      Der_class class, Der_type type, int tag, size_t * size)
+der_put_visible_string (unsigned char *p, size_t len,
+                        const heim_visible_string *str, size_t *size)
 {
-    size_t ret = 0;
-    size_t l;
-    int e;
+    return der_put_general_string(p, len, str, size);
+}
 
-    e = der_put_length(p, len, len_val, &l);
-    if (e)
-       return e;
-    p -= l;
-    len -= l;
-    ret += l;
-    e = der_put_tag(p, len, class, type, tag, &l);
-    if (e)
-       return e;
-    p -= l;
-    len -= l;
-    ret += l;
-    *size = ret;
+int
+der_put_octet_string (unsigned char *p, size_t len,
+                     const heim_octet_string *data, size_t *size)
+{
+    if (len < data->length)
+       return ASN1_OVERFLOW;
+    p -= data->length;
+    memcpy (p+1, data->data, data->length);
+    *size = data->length;
     return 0;
 }
 
 int
-encode_integer(unsigned char *p, size_t len, const int *data, size_t * size)
+der_put_heim_integer (unsigned char *p, size_t len,
+                    const heim_integer *data, size_t *size)
 {
-    int num = *data;
-    size_t ret = 0;
-    size_t l;
-    int e;
+    unsigned char *buf = data->data;
+    int hibitset = 0;
 
-    e = der_put_int(p, len, num, &l);
-    if (e)
-       return e;
-    p -= l;
-    len -= l;
-    ret += l;
-    e = der_put_length_and_tag(p, len, l, UNIV, PRIM, UT_Integer, &l);
-    if (e)
-       return e;
-    p -= l;
-    len -= l;
-    ret += l;
-    *size = ret;
+    if (data->length == 0) {
+       if (len < 1)
+           return ASN1_OVERFLOW;
+       *p-- = 0;
+       if (size)
+           *size = 1;
+       return 0;
+    }
+    if (len < data->length)
+       return ASN1_OVERFLOW;
+
+    len -= data->length;
+
+    if (data->negative) {
+       int i, carry;
+       for (i = data->length - 1, carry = 1; i >= 0; i--) {
+           *p = buf[i] ^ 0xff;
+           if (carry)
+               carry = !++*p;
+           p--;
+       }
+       if (p[1] < 128) {
+           if (len < 1)
+               return ASN1_OVERFLOW;
+           *p-- = 0xff;
+           len--;
+           hibitset = 1;
+       }
+    } else {
+       p -= data->length;
+       memcpy(p + 1, buf, data->length);
+
+       if (p[1] >= 128) {
+           if (len < 1)
+               return ASN1_OVERFLOW;
+           p[0] = 0;
+           len--;
+           hibitset = 1;
+       }
+    }
+    if (size)
+       *size = data->length + hibitset;
     return 0;
 }
 
 int
-encode_unsigned(unsigned char *p, size_t len, const unsigned *data,
-               size_t * size)
+der_put_generalized_time (unsigned char *p, size_t len,
+                         const time_t *data, size_t *size)
 {
-    unsigned num = *data;
-    size_t ret = 0;
+    heim_octet_string k;
     size_t l;
     int e;
 
-    e = der_put_unsigned(p, len, num, &l);
+    e = _heim_time2generalizedtime (*data, &k, 1);
     if (e)
        return e;
-    p -= l;
-    len -= l;
-    ret += l;
-    e = der_put_length_and_tag(p, len, l, UNIV, PRIM, UT_Integer, &l);
-    if (e)
+    e = der_put_octet_string(p, len, &k, &l);
+    free(k.data);
+    if(e)
        return e;
-    p -= l;
-    len -= l;
-    ret += l;
-    *size = ret;
+    if(size)
+       *size = l;
     return 0;
 }
 
 int
-encode_enumerated(unsigned char *p, size_t len, const unsigned *data,
-                 size_t * size)
+der_put_utctime (unsigned char *p, size_t len,
+                const time_t *data, size_t *size)
 {
-    unsigned num = *data;
-    size_t ret = 0;
+    heim_octet_string k;
     size_t l;
     int e;
 
-    e = der_put_int(p, len, num, &l);
+    e = _heim_time2generalizedtime (*data, &k, 0);
     if (e)
        return e;
-    p -= l;
-    len -= l;
-    ret += l;
-    e = der_put_length_and_tag(p, len, l, UNIV, PRIM, UT_Enumerated, &l);
-    if (e)
+    e = der_put_octet_string(p, len, &k, &l);
+    free(k.data);
+    if(e)
        return e;
-    p -= l;
-    len -= l;
-    ret += l;
-    *size = ret;
+    if(size)
+       *size = l;
     return 0;
 }
 
 int
-encode_general_string(unsigned char *p, size_t len,
-                     const general_string * data, size_t * size)
+der_put_oid (unsigned char *p, size_t len,
+            const heim_oid *data, size_t *size)
 {
-    size_t ret = 0;
-    size_t l;
-    int e;
+    unsigned char *base = p;
+    int n;
 
-    e = der_put_general_string(p, len, data, &l);
-    if (e)
-       return e;
-    p -= l;
-    len -= l;
-    ret += l;
-    e = der_put_length_and_tag(p, len, l, UNIV, PRIM, UT_GeneralString, &l);
-    if (e)
-       return e;
-    p -= l;
-    len -= l;
-    ret += l;
-    *size = ret;
+    for (n = data->length - 1; n >= 2; --n) {
+       unsigned u = data->components[n];
+
+       if (len < 1)
+           return ASN1_OVERFLOW;
+       *p-- = u % 128;
+       u /= 128;
+       --len;
+       while (u > 0) {
+           if (len < 1)
+               return ASN1_OVERFLOW;
+           *p-- = 128 + u % 128;
+           u /= 128;
+           --len;
+       }
+    }
+    if (len < 1)
+       return ASN1_OVERFLOW;
+    *p-- = 40 * data->components[0] + data->components[1];
+    *size = base - p;
     return 0;
 }
 
 int
-encode_octet_string(unsigned char *p, size_t len, const octet_string * k,
-                   size_t * size)
+der_put_tag (unsigned char *p, size_t len, Der_class class, Der_type type,
+            unsigned int tag, size_t *size)
 {
-    size_t ret = 0;
-    size_t l;
-    int e;
+    if (tag <= 30) {
+       if (len < 1)
+           return ASN1_OVERFLOW;
+       *p = MAKE_TAG(class, type, tag);
+       *size = 1;
+    } else {
+       size_t ret = 0;
+       unsigned int continuation = 0;
 
-    e = der_put_octet_string(p, len, k, &l);
-    if (e)
-       return e;
-    p -= l;
-    len -= l;
-    ret += l;
-    e = der_put_length_and_tag(p, len, l, UNIV, PRIM, UT_OctetString, &l);
-    if (e)
-       return e;
-    p -= l;
-    len -= l;
-    ret += l;
-    *size = ret;
+       do {
+           if (len < 1)
+               return ASN1_OVERFLOW;
+           *p-- = tag % 128 | continuation;
+           len--;
+           ret++;
+           tag /= 128;
+           continuation = 0x80;
+       } while(tag > 0);
+       if (len < 1)
+           return ASN1_OVERFLOW;
+       *p-- = MAKE_TAG(class, type, 0x1f);
+       ret++;
+       *size = ret;
+    }
     return 0;
 }
 
 int
-encode_oid(unsigned char *p, size_t len, const oid * k, size_t * size)
+der_put_length_and_tag (unsigned char *p, size_t len, size_t len_val,
+                       Der_class class, Der_type type,
+                       unsigned int tag, size_t *size)
 {
     size_t ret = 0;
     size_t l;
     int e;
 
-    e = der_put_oid(p, len, k, &l);
-    if (e)
+    e = der_put_length (p, len, len_val, &l);
+    if(e)
        return e;
     p -= l;
     len -= l;
     ret += l;
-    e = der_put_length_and_tag(p, len, l, UNIV, PRIM, UT_OID, &l);
-    if (e)
+    e = der_put_tag (p, len, class, type, tag, &l);
+    if(e)
        return e;
-    p -= l;
-    len -= l;
+
     ret += l;
     *size = ret;
     return 0;
 }
 
 int
-time2generalizedtime(time_t t, octet_string * s)
+_heim_time2generalizedtime (time_t t, heim_octet_string *s, int gtimep)
 {
-    struct tm *tm;
-
-    s->data = malloc(16);
-    if (s->data == NULL)
-       return ENOMEM;
-    s->length = 15;
-    tm = gmtime(&t);
-    sprintf(s->data, "%04d%02d%02d%02d%02d%02dZ", tm->tm_year + 1900,
-           tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec);
-    return 0;
+     struct tm *tm;
+     const size_t len = gtimep ? 15 : 13;
+
+     s->data = malloc(len + 1);
+     if (s->data == NULL)
+        return ENOMEM;
+     s->length = len;
+     tm = gmtime (&t);
+     if (gtimep)
+        snprintf (s->data, len + 1, "%04d%02d%02d%02d%02d%02dZ",
+                  tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
+                  tm->tm_hour, tm->tm_min, tm->tm_sec);
+     else
+        snprintf (s->data, len + 1, "%02d%02d%02d%02d%02d%02dZ",
+                  tm->tm_year % 100, tm->tm_mon + 1, tm->tm_mday,
+                  tm->tm_hour, tm->tm_min, tm->tm_sec);
+
+     return 0;
 }
 
 int
-encode_generalized_time(unsigned char *p, size_t len, const time_t * t,
-                       size_t * size)
+der_put_bit_string (unsigned char *p, size_t len,
+                   const heim_bit_string *data, size_t *size)
 {
-    size_t ret = 0;
-    size_t l;
-    octet_string k;
-    int e;
+    size_t data_size = (data->length + 7) / 8;
+    if (len < data_size + 1)
+       return ASN1_OVERFLOW;
+    p -= data_size + 1;
 
-    e = time2generalizedtime(*t, &k);
-    if (e)
-       return e;
-    e = der_put_octet_string(p, len, &k, &l);
-    free(k.data);
-    if (e)
-       return e;
-    p -= l;
-    len -= l;
-    ret += l;
-    e = der_put_length_and_tag(p, len, k.length, UNIV, PRIM,
-                              UT_GeneralizedTime, &l);
-    if (e)
-       return e;
-    p -= l;
-    len -= l;
-    ret += l;
-    *size = ret;
+    memcpy (p+2, data->data, data_size);
+    if (data->length && (data->length % 8) != 0)
+       p[1] = 8 - (data->length % 8);
+    else
+       p[1] = 0;
+    *size = data_size + 1;
     return 0;
 }
 
+int
+_heim_der_set_sort(const void *a1, const void *a2)
+{
+    const struct heim_octet_string *s1 = a1, *s2 = a2;
+    int ret;
+
+    ret = memcmp(s1->data, s2->data,
+                s1->length < s2->length ? s1->length : s2->length);
+    if(ret)
+       return ret;
+    return s1->length - s2->length;
+}
 /*
- * Copyright (c) 1997 - 2001 Kungliga Tekniska Högskolan
- * (Royal Institute of Technology, Stockholm, Sweden). 
- * All rights reserved. 
+ * Copyright (c) 1997 - 2005 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: 
+ * Portions Copyright (c) 2009 Apple Inc. All rights reserved.
  *
- * 1. Redistributions of source code must retain the above copyright 
- *    notice, this list of conditions and the following disclaimer. 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
  *
- * 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. 
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
  *
- * 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. 
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
  *
- * THIS SOFTWARE IS PROVIDED BY THE 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. 
+ * 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.
  */
 
 
-/* RCSID("Heimdal: der_free.c,v 1.8 2001/09/25 13:39:26 assar Exp $"); */
+/* RCSID("$Id$"); */
 
 void
-free_general_string(general_string * str)
+der_free_general_string (heim_general_string *str)
 {
     free(*str);
+    *str = NULL;
+}
+
+void
+der_free_integer (int *i)
+{
+    *i = 0;
+}
+
+void
+der_free_unsigned (unsigned *u)
+{
+    *u = 0;
 }
 
 void
-free_octet_string(octet_string * k)
+der_free_generalized_time(time_t *t)
+{
+    *t = 0;
+}
+
+void
+der_free_utctime(time_t *t)
+{
+    *t = 0;
+}
+
+
+void
+der_free_utf8string (heim_utf8_string *str)
+{
+    free(*str);
+    *str = NULL;
+}
+
+void
+der_free_printable_string (heim_printable_string *str)
+{
+    free(*str);
+    *str = NULL;
+}
+
+void
+der_free_ia5_string (heim_ia5_string *str)
+{
+    free(*str);
+    *str = NULL;
+}
+
+void
+der_free_bmp_string (heim_bmp_string *k)
+{
+    free(k->data);
+    k->data = NULL;
+    k->length = 0;
+}
+
+void
+der_free_universal_string (heim_universal_string *k)
+{
+    free(k->data);
+    k->data = NULL;
+    k->length = 0;
+}
+
+void
+der_free_visible_string (heim_visible_string *str)
+{
+    free(*str);
+    *str = NULL;
+}
+
+void
+der_free_octet_string (heim_octet_string *k)
 {
     free(k->data);
+    k->data = NULL;
+    k->length = 0;
 }
 
 void
-free_oid(oid * k)
+der_free_heim_integer (heim_integer *k)
+{
+    free(k->data);
+    k->data = NULL;
+    k->length = 0;
+}
+
+void
+der_free_oid (heim_oid *k)
 {
     free(k->components);
+    k->components = NULL;
+    k->length = 0;
 }
 
+void
+der_free_bit_string (heim_bit_string *k)
+{
+    free(k->data);
+    k->data = NULL;
+    k->length = 0;
+}
 /*
- * Copyright (c) 1997 - 2001 Kungliga Tekniska Högskolan
- * (Royal Institute of Technology, Stockholm, Sweden). 
- * All rights reserved. 
+ * Copyright (c) 1997-2005 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Portions Copyright (c) 2009 Apple Inc. All rights reserved.
  *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions 
- * are met: 
+ * 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. 
+ * 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. 
+ * 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. 
+ * 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. 
+ * 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.
  */
 
 
-/* RCSID("Heimdal: der_length.c,v 1.12 2001/09/25 13:39:26 assar Exp $"); */
+/* RCSID("$Id$"); */
 
-static size_t
-len_unsigned(unsigned val)
+size_t
+_heim_len_unsigned (unsigned val)
 {
     size_t ret = 0;
+    int last_val_gt_128;
 
     do {
        ++ret;
+       last_val_gt_128 = (val >= 128);
        val /= 256;
     } while (val);
+
+    if(last_val_gt_128)
+       ret++;
+
     return ret;
 }
 
-static size_t
-len_int(int val)
+size_t
+_heim_len_int (int val)
 {
+    unsigned char q;
     size_t ret = 0;
 
-    if (val == 0)
-       return 1;
-    while (val > 255 || val < -255) {
-       ++ret;
-       val /= 256;
-    }
-    if (val != 0) {
-       ++ret;
-       if ((signed char)val != val)
-           ++ret;
-       val /= 256;
+    if (val >= 0) {
+       do {
+           q = val % 256;
+           ret++;
+           val /= 256;
+       } while(val);
+       if(q >= 128)
+           ret++;
+    } else {
+       val = ~val;
+       do {
+           q = ~(val % 256);
+           ret++;
+           val /= 256;
+       } while(val);
+       if(q < 128)
+           ret++;
     }
     return ret;
 }
 
 static size_t
-len_oid(const oid * oid)
+len_oid (const heim_oid *oid)
 {
     size_t ret = 1;
     int n;
@@ -1063,219 +1438,332 @@ len_oid(const oid * oid)
     for (n = 2; n < oid->length; ++n) {
        unsigned u = oid->components[n];
 
-       ++ret;
-       u /= 128;
-       while (u > 0) {
+       do {
            ++ret;
            u /= 128;
-       }
+       } while(u > 0);
     }
     return ret;
 }
 
 size_t
-length_len(size_t len)
+der_length_len (size_t len)
 {
     if (len < 128)
        return 1;
-    else
-       return len_unsigned(len) + 1;
+    else {
+       int ret = 0;
+       do {
+           ++ret;
+           len /= 256;
+       } while (len);
+       return ret + 1;
+    }
 }
 
 size_t
-length_integer(const int *data)
+der_length_tag(unsigned int tag)
 {
-    size_t len = len_int(*data);
+    size_t len = 0;
 
-    return 1 + length_len(len) + len;
+    if(tag <= 30)
+       return 1;
+    while(tag) {
+       tag /= 128;
+       len++;
+    }
+    return len + 1;
 }
 
 size_t
-length_unsigned(const unsigned *data)
+der_length_integer (const int *data)
 {
-    size_t len = len_unsigned(*data);
+    return _heim_len_int (*data);
+}
 
-    return 1 + length_len(len) + len;
+size_t
+der_length_unsigned (const unsigned *data)
+{
+    return _heim_len_unsigned(*data);
 }
 
 size_t
-length_enumerated(const unsigned *data)
+der_length_enumerated (const unsigned *data)
 {
-    size_t len = len_int(*data);
+  return _heim_len_int (*data);
+}
 
-    return 1 + length_len(len) + len;
+size_t
+der_length_general_string (const heim_general_string *data)
+{
+    return strlen(*data);
 }
 
 size_t
-length_general_string(const general_string * data)
+der_length_utf8string (const heim_utf8_string *data)
 {
-    char *str = *data;
-    size_t len = strlen(str);
-    return 1 + length_len(len) + len;
+    return strlen(*data);
 }
 
 size_t
-length_octet_string(const octet_string * k)
+der_length_printable_string (const heim_printable_string *data)
 {
-    return 1 + length_len(k->length) + k->length;
+    return strlen(*data);
 }
 
 size_t
-length_oid(const oid * k)
+der_length_ia5_string (const heim_ia5_string *data)
 {
-    size_t len = len_oid(k);
+    return strlen(*data);
+}
 
-    return 1 + length_len(len) + len;
+size_t
+der_length_bmp_string (const heim_bmp_string *data)
+{
+    return data->length * 2;
 }
 
 size_t
-length_generalized_time(const time_t * t)
+der_length_universal_string (const heim_universal_string *data)
 {
-    octet_string k;
+    return data->length * 4;
+}
+
+size_t
+der_length_visible_string (const heim_visible_string *data)
+{
+    return strlen(*data);
+}
+
+size_t
+der_length_octet_string (const heim_octet_string *k)
+{
+    return k->length;
+}
+
+size_t
+der_length_heim_integer (const heim_integer *k)
+{
+    if (k->length == 0)
+       return 1;
+    if (k->negative)
+       return k->length + (((~(((unsigned char *)k->data)[0])) & 0x80) ? 0 : 1);
+    else
+       return k->length + ((((unsigned char *)k->data)[0] & 0x80) ? 1 : 0);
+}
+
+size_t
+der_length_oid (const heim_oid *k)
+{
+    return len_oid (k);
+}
+
+size_t
+der_length_generalized_time (const time_t *t)
+{
+    heim_octet_string k;
+    size_t ret;
+
+    _heim_time2generalizedtime (*t, &k, 1);
+    ret = k.length;
+    free(k.data);
+    return ret;
+}
+
+size_t
+der_length_utctime (const time_t *t)
+{
+    heim_octet_string k;
     size_t ret;
 
-    time2generalizedtime(*t, &k);
-    ret = 1 + length_len(k.length) + k.length;
+    _heim_time2generalizedtime (*t, &k, 0);
+    ret = k.length;
     free(k.data);
     return ret;
 }
 
+size_t
+der_length_boolean (const int *k)
+{
+    return 1;
+}
+
+size_t
+der_length_bit_string (const heim_bit_string *k)
+{
+    return (k->length + 7) / 8 + 1;
+}
 /*
- * Copyright (c) 1997 - 2001 Kungliga Tekniska Högskolan
- * (Royal Institute of Technology, Stockholm, Sweden). 
- * All rights reserved. 
+ * Copyright (c) 1997 - 2006 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Portions Copyright (c) 2009 Apple Inc. All rights reserved.
  *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions 
- * are met: 
+ * 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. 
+ * 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. 
+ * 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. 
+ * 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. 
+ * 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.
  */
 
 
-/* RCSID("Heimdal: der_copy.c,v 1.9 2001/09/25 13:39:25 assar Exp $"); */
+/* RCSID("$Id$"); */
 
 int
-copy_general_string(const general_string * from, general_string * to)
+der_copy_general_string (const heim_general_string *from,
+                        heim_general_string *to)
 {
-    *to = malloc(strlen(*from) + 1);
-    if (*to == NULL)
+    *to = strdup(*from);
+    if(*to == NULL)
        return ENOMEM;
-    strcpy(*to, *from);
     return 0;
 }
 
 int
-copy_octet_string(const octet_string * from, octet_string * to)
+der_copy_integer (const int *from, int *to)
+{
+    *to = *from;
+    return 0;
+}
+
+int
+der_copy_unsigned (const unsigned *from, unsigned *to)
+{
+    *to = *from;
+    return 0;
+}
+
+int
+der_copy_generalized_time (const time_t *from, time_t *to)
+{
+    *to = *from;
+    return 0;
+}
+
+int
+der_copy_utctime (const time_t *from, time_t *to)
+{
+    *to = *from;
+    return 0;
+}
+
+int
+der_copy_utf8string (const heim_utf8_string *from, heim_utf8_string *to)
+{
+    return der_copy_general_string(from, to);
+}
+
+int
+der_copy_printable_string (const heim_printable_string *from,
+                      heim_printable_string *to)
+{
+    return der_copy_general_string(from, to);
+}
+
+int
+der_copy_ia5_string (const heim_printable_string *from,
+                    heim_printable_string *to)
+{
+    return der_copy_general_string(from, to);
+}
+
+int
+der_copy_bmp_string (const heim_bmp_string *from, heim_bmp_string *to)
 {
     to->length = from->length;
-    to->data = malloc(to->length);
-    if (to->length != 0 && to->data == NULL)
+    to->data   = malloc(to->length * sizeof(to->data[0]));
+    if(to->length != 0 && to->data == NULL)
        return ENOMEM;
-    memcpy(to->data, from->data, to->length);
+    memcpy(to->data, from->data, to->length * sizeof(to->data[0]));
     return 0;
 }
 
 int
-copy_oid(const oid * from, oid * to)
+der_copy_universal_string (const heim_universal_string *from,
+                          heim_universal_string *to)
 {
     to->length = from->length;
-    to->components = malloc(to->length * sizeof(*to->components));
-    if (to->length != 0 && to->components == NULL)
+    to->data   = malloc(to->length * sizeof(to->data[0]));
+    if(to->length != 0 && to->data == NULL)
        return ENOMEM;
-    memcpy(to->components, from->components, to->length);
+    memcpy(to->data, from->data, to->length * sizeof(to->data[0]));
     return 0;
 }
 
-/*
- * Copyright (c) 1997 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. 
- */
-
+int
+der_copy_visible_string (const heim_visible_string *from,
+                        heim_visible_string *to)
+{
+    return der_copy_general_string(from, to);
+}
 
-/* RCSID("Heimdal: timegm.c,v 1.7 1999/12/02 17:05:02 joda Exp $"); */
+int
+der_copy_octet_string (const heim_octet_string *from, heim_octet_string *to)
+{
+    to->length = from->length;
+    to->data   = malloc(to->length);
+    if(to->length != 0 && to->data == NULL)
+       return ENOMEM;
+    memcpy(to->data, from->data, to->length);
+    return 0;
+}
 
-#ifndef HAVE_TIMEGM
+int
+der_copy_heim_integer (const heim_integer *from, heim_integer *to)
+{
+    to->length = from->length;
+    to->data   = malloc(to->length);
+    if(to->length != 0 && to->data == NULL)
+       return ENOMEM;
+    memcpy(to->data, from->data, to->length);
+    to->negative = from->negative;
+    return 0;
+}
 
-static int
-is_leap(unsigned y)
+int
+der_copy_oid (const heim_oid *from, heim_oid *to)
 {
-    y += 1900;
-    return (y % 4) == 0 && ((y % 100) != 0 || (y % 400) == 0);
+    to->length     = from->length;
+    to->components = malloc(to->length * sizeof(*to->components));
+    if (to->length != 0 && to->components == NULL)
+       return ENOMEM;
+    memcpy(to->components, from->components,
+          to->length * sizeof(*to->components));
+    return 0;
 }
 
-time_t
-timegm(struct tm * tm)
-{
-    static const unsigned ndays[2][12] = {
-       {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
-       {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
-    };
-    time_t res = 0;
-    unsigned i;
-
-    for (i = 70; i < tm->tm_year; ++i)
-       res += is_leap(i) ? 366 : 365;
-
-    for (i = 0; i < tm->tm_mon; ++i)
-       res += ndays[is_leap(tm->tm_year)][i];
-    res += tm->tm_mday - 1;
-    res *= 24;
-    res += tm->tm_hour;
-    res *= 60;
-    res += tm->tm_min;
-    res *= 60;
-    res += tm->tm_sec;
-    return res;
-}
-
-#endif /* HAVE_TIMEGM */
+int
+der_copy_bit_string (const heim_bit_string *from, heim_bit_string *to)
+{
+    size_t len;
+
+    len = (from->length + 7) / 8;
+    to->length = from->length;
+    to->data   = malloc(len);
+    if(len != 0 && to->data == NULL)
+       return ENOMEM;
+    memcpy(to->data, from->data, len);
+    return 0;
+}
index b6087c4..60aa227 100644 (file)
@@ -1,4 +1,4 @@
-/* Generated from /home/lha/src/cvs/heimdal/lib/asn1/k5.asn1 */
+/* Generated from ./krb5.asn1 */
 /* Do not edit */
 
 #include <stdio.h>
 #include <time.h>
 #include <string.h>
 #include <errno.h>
-#include "asn1_err.h"
+#include <limits.h>
+#include <asn1_err.h>
+
+int
+encode_krb5int32(unsigned char *p, size_t len, const krb5int32 * data, size_t * size)
+{
+    size_t ret = 0;
+    size_t l;
+    int i, e;
+
+    i = 0;
+    e = der_put_integer(p, len, data, &l);
+    if (e)
+       return e;
+    p -= l;
+    len -= l;
+    ret += l;
+
+    e = der_put_length_and_tag(p, len, ret, ASN1_C_UNIV, PRIM, UT_Integer, &l);
+    if (e)
+       return e;
+    p -= l;
+    len -= l;
+    ret += l;
+
+    *size = ret;
+    return 0;
+}
+
+int
+decode_krb5int32(const unsigned char *p, size_t len, krb5int32 * data, size_t * size)
+{
+    size_t ret = 0;
+    size_t l;
+    int e;
+
+    memset(data, 0, sizeof(*data));
+    {
+       size_t Top_datalen, Top_oldlen;
+       Der_type Top_type;
+       e = der_match_tag_and_length(p, len, ASN1_C_UNIV, &Top_type, UT_Integer, &Top_datalen, &l);
+       if (e == 0 && Top_type != PRIM) {
+           e = ASN1_BAD_ID;
+       }
+       if (e)
+           goto fail;
+       p += l;
+       len -= l;
+       ret += l;
+       Top_oldlen = len;
+       if (Top_datalen > len) {
+           e = ASN1_OVERRUN;
+           goto fail;
+       }
+       len = Top_datalen;
+       e = der_get_integer(p, len, data, &l);
+       if (e)
+           goto fail;
+       p += l;
+       len -= l;
+       ret += l;
+       len = Top_oldlen - Top_datalen;
+    }
+    if (size)
+       *size = ret;
+    return 0;
+fail:
+    free_krb5int32(data);
+    return e;
+}
+
+void
+free_krb5int32(krb5int32 * data)
+{
+}
+
+size_t
+length_krb5int32(const krb5int32 * data)
+{
+    size_t ret = 0;
+    ret += der_length_integer(data);
+    ret += 1 + der_length_len(ret);
+    return ret;
+}
+
+int
+copy_krb5int32(const krb5int32 * from, krb5int32 * to)
+{
+    memset(to, 0, sizeof(*to));
+    *(to) = *(from);
+    return 0;
+}
+
+
 
-#define BACK if (e) return e; p -= l; len -= l; ret += l
+/* Generated from ./krb5.asn1 */
+/* Do not edit */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <string.h>
+#include <errno.h>
+#include <limits.h>
+#include <asn1_err.h>
 
 int
-encode_Ticket(unsigned char *p, size_t len, const Ticket * data,
-             size_t * size)
+encode_Ticket(unsigned char *p, size_t len, const Ticket * data, size_t * size)
 {
     size_t ret = 0;
     size_t l;
     int i, e;
 
     i = 0;
+/* enc-part */
     {
-       int oldret = ret;
+       size_t Top_tag_tag_oldret = ret;
        ret = 0;
        e = encode_EncryptedData(p, len, &(data)->enc_part, &l);
-       BACK;
-       e = der_put_length_and_tag(p, len, ret, Der_CONTEXT, CONS, 3, &l);
-       BACK;
-       ret += oldret;
-    }
+       if (e)
+           return e;
+       p -= l;
+       len -= l;
+       ret += l;
+
+       e = der_put_length_and_tag(p, len, ret, ASN1_C_CONTEXT, CONS, 3, &l);
+       if (e)
+           return e;
+       p -= l;
+       len -= l;
+       ret += l;
+
+       ret += Top_tag_tag_oldret;
+    }
+/* sname */
     {
-       int oldret = ret;
+       size_t Top_tag_tag_oldret = ret;
        ret = 0;
        e = encode_PrincipalName(p, len, &(data)->sname, &l);
-       BACK;
-       e = der_put_length_and_tag(p, len, ret, Der_CONTEXT, CONS, 2, &l);
-       BACK;
-       ret += oldret;
-    }
+       if (e)
+           return e;
+       p -= l;
+       len -= l;
+       ret += l;
+
+       e = der_put_length_and_tag(p, len, ret, ASN1_C_CONTEXT, CONS, 2, &l);
+       if (e)
+           return e;
+       p -= l;
+       len -= l;
+       ret += l;
+
+       ret += Top_tag_tag_oldret;
+    }
+/* realm */
     {
-       int oldret = ret;
+       size_t Top_tag_tag_oldret = ret;
        ret = 0;
        e = encode_Realm(p, len, &(data)->realm, &l);
-       BACK;
-       e = der_put_length_and_tag(p, len, ret, Der_CONTEXT, CONS, 1, &l);
-       BACK;
-       ret += oldret;
-    }
+       if (e)
+           return e;
+       p -= l;
+       len -= l;
+       ret += l;
+
+       e = der_put_length_and_tag(p, len, ret, ASN1_C_CONTEXT, CONS, 1, &l);
+       if (e)
+           return e;
+       p -= l;
+       len -= l;
+       ret += l;
+
+       ret += Top_tag_tag_oldret;
+    }
+/* tkt-vno */
     {
-       int oldret = ret;
+       size_t Top_tag_tag_oldret = ret;
        ret = 0;
-       e = encode_integer(p, len, &(data)->tkt_vno, &l);
-       BACK;
-       e = der_put_length_and_tag(p, len, ret, Der_CONTEXT, CONS, 0, &l);
-       BACK;
-       ret += oldret;
-    }
-    e = der_put_length_and_tag(p, len, ret, UNIV, CONS, UT_Sequence, &l);
-    BACK;
-    e = der_put_length_and_tag(p, len, ret, APPL, CONS, 1, &l);
-    BACK;
+       e = encode_krb5int32(p, len, &(data)->tkt_vno, &l);
+       if (e)
+           return e;
+       p -= l;
+       len -= l;
+       ret += l;
+
+       e = der_put_length_and_tag(p, len, ret, ASN1_C_CONTEXT, CONS, 0, &l);
+       if (e)
+           return e;
+       p -= l;
+       len -= l;
+       ret += l;
+
+       ret += Top_tag_tag_oldret;
+    }
+    e = der_put_length_and_tag(p, len, ret, ASN1_C_UNIV, CONS, UT_Sequence, &l);
+    if (e)
+       return e;
+    p -= l;
+    len -= l;
+    ret += l;
+
+    e = der_put_length_and_tag(p, len, ret, ASN1_C_APPL, CONS, 1, &l);
+    if (e)
+       return e;
+    p -= l;
+    len -= l;
+    ret += l;
+
     *size = ret;
     return 0;
 }
 
-#define FORW if(e) goto fail; p += l; len -= l; ret += l
-
 int
-decode_Ticket(const unsigned char *p, size_t len, Ticket * data,
-             size_t * size)
+decode_Ticket(const unsigned char *p, size_t len, Ticket * data, size_t * size)
 {
-    size_t ret = 0, reallen;
+    size_t ret = 0;
     size_t l;
     int e;
 
     memset(data, 0, sizeof(*data));
-    reallen = 0;
-    e = der_match_tag_and_length(p, len, APPL, CONS, 1, &reallen, &l);
-    FORW;
-    {
-       int dce_fix;
-       if ((dce_fix = fix_dce(reallen, &len)) < 0)
-           return ASN1_BAD_FORMAT;
-       e = der_match_tag_and_length(p, len, UNIV, CONS, UT_Sequence,
-                                    &reallen, &l);
-       FORW;
+    {
+       size_t Top_datalen, Top_oldlen;
+       Der_type Top_type;
+       e = der_match_tag_and_length(p, len, ASN1_C_APPL, &Top_type, 1, &Top_datalen, &l);
+       if (e == 0 && Top_type != CONS) {
+           e = ASN1_BAD_ID;
+       }
+       if (e)
+           goto fail;
+       p += l;
+       len -= l;
+       ret += l;
+       Top_oldlen = len;
+       if (Top_datalen > len) {
+           e = ASN1_OVERRUN;
+           goto fail;
+       }
+       len = Top_datalen;
        {
-           int dce_fix;
-           if ((dce_fix = fix_dce(reallen, &len)) < 0)
-               return ASN1_BAD_FORMAT;
+           size_t Top_Tag_datalen, Top_Tag_oldlen;
+           Der_type Top_Tag_type;
+           e = der_match_tag_and_length(p, len, ASN1_C_UNIV, &Top_Tag_type, UT_Sequence, &Top_Tag_datalen, &l);
+           if (e == 0 && Top_Tag_type != CONS) {
+               e = ASN1_BAD_ID;
+           }
+           if (e)
+               goto fail;
+           p += l;
+           len -= l;
+           ret += l;
+           Top_Tag_oldlen = len;
+           if (Top_Tag_datalen > len) {
+               e = ASN1_OVERRUN;
+               goto fail;
+           }
+           len = Top_Tag_datalen;
            {
-               size_t newlen, oldlen;
-
-               e = der_match_tag(p, len, Der_CONTEXT, CONS, 0, &l);
+               size_t tkt_vno_datalen, tkt_vno_oldlen;
+               Der_type tkt_vno_type;
+               e = der_match_tag_and_length(p, len, ASN1_C_CONTEXT, &tkt_vno_type, 0, &tkt_vno_datalen, &l);
+               if (e == 0 && tkt_vno_type != CONS) {
+                   e = ASN1_BAD_ID;
+               }
                if (e)
-                   return e;
-               else {
-                   p += l;
-                   len -= l;
-                   ret += l;
-                   e = der_get_length(p, len, &newlen, &l);
-                   FORW;
-                   {
-                       int dce_fix;
-                       oldlen = len;
-                       if ((dce_fix = fix_dce(newlen, &len)) < 0)
-                           return ASN1_BAD_FORMAT;
-                       e = decode_integer(p, len, &(data)->tkt_vno, &l);
-                       FORW;
-                       if (dce_fix) {
-                           e = der_match_tag_and_length(p, len,
-                                                        (Der_class) 0,
-                                                        (Der_type) 0, 0,
-                                                        &reallen, &l);
-                           FORW;
-                       } else
-                           len = oldlen - newlen;
-                   }
+                   goto fail;
+               p += l;
+               len -= l;
+               ret += l;
+               tkt_vno_oldlen = len;
+               if (tkt_vno_datalen > len) {
+                   e = ASN1_OVERRUN;
+                   goto fail;
                }
+               len = tkt_vno_datalen;
+               e = decode_krb5int32(p, len, &(data)->tkt_vno, &l);
+               if (e)
+                   goto fail;
+               p += l;
+               len -= l;
+               ret += l;
+               len = tkt_vno_oldlen - tkt_vno_datalen;
            }
            {
-               size_t newlen, oldlen;
-
-               e = der_match_tag(p, len, Der_CONTEXT, CONS, 1, &l);
+               size_t realm_datalen, realm_oldlen;
+               Der_type realm_type;
+               e = der_match_tag_and_length(p, len, ASN1_C_CONTEXT, &realm_type, 1, &realm_datalen, &l);
+               if (e == 0 && realm_type != CONS) {
+                   e = ASN1_BAD_ID;
+               }
                if (e)
-                   return e;
-               else {
-                   p += l;
-                   len -= l;
-                   ret += l;
-                   e = der_get_length(p, len, &newlen, &l);
-                   FORW;
-                   {
-                       int dce_fix;
-                       oldlen = len;
-                       if ((dce_fix = fix_dce(newlen, &len)) < 0)
-                           return ASN1_BAD_FORMAT;
-                       e = decode_Realm(p, len, &(data)->realm, &l);
-                       FORW;
-                       if (dce_fix) {
-                           e = der_match_tag_and_length(p, len,
-                                                        (Der_class) 0,
-                                                        (Der_type) 0, 0,
-                                                        &reallen, &l);
-                           FORW;
-                       } else
-                           len = oldlen - newlen;
-                   }
+                   goto fail;
+               p += l;
+               len -= l;
+               ret += l;
+               realm_oldlen = len;
+               if (realm_datalen > len) {
+                   e = ASN1_OVERRUN;
+                   goto fail;
                }
+               len = realm_datalen;
+               e = decode_Realm(p, len, &(data)->realm, &l);
+               if (e)
+                   goto fail;
+               p += l;
+               len -= l;
+               ret += l;
+               len = realm_oldlen - realm_datalen;
            }
            {
-               size_t newlen, oldlen;
-
-               e = der_match_tag(p, len, Der_CONTEXT, CONS, 2, &l);
+               size_t sname_datalen, sname_oldlen;
+               Der_type sname_type;
+               e = der_match_tag_and_length(p, len, ASN1_C_CONTEXT, &sname_type, 2, &sname_datalen, &l);
+               if (e == 0 && sname_type != CONS) {
+                   e = ASN1_BAD_ID;
+               }
                if (e)
-                   return e;
-               else {
-                   p += l;
-                   len -= l;
-                   ret += l;
-                   e = der_get_length(p, len, &newlen, &l);
-                   FORW;
-                   {
-                       int dce_fix;
-                       oldlen = len;
-                       if ((dce_fix = fix_dce(newlen, &len)) < 0)
-                           return ASN1_BAD_FORMAT;
-                       e = decode_PrincipalName(p, len, &(data)->sname, &l);
-                       FORW;
-                       if (dce_fix) {
-                           e = der_match_tag_and_length(p, len,
-                                                        (Der_class) 0,
-                                                        (Der_type) 0, 0,
-                                                        &reallen, &l);
-                           FORW;
-                       } else
-                           len = oldlen - newlen;
-                   }
+                   goto fail;
+               p += l;
+               len -= l;
+               ret += l;
+               sname_oldlen = len;
+               if (sname_datalen > len) {
+                   e = ASN1_OVERRUN;
+                   goto fail;
                }
+               len = sname_datalen;
+               e = decode_PrincipalName(p, len, &(data)->sname, &l);
+               if (e)
+                   goto fail;
+               p += l;
+               len -= l;
+               ret += l;
+               len = sname_oldlen - sname_datalen;
            }
            {
-               size_t newlen, oldlen;
-
-               e = der_match_tag(p, len, Der_CONTEXT, CONS, 3, &l);
+               size_t enc_part_datalen, enc_part_oldlen;
+               Der_type enc_part_type;
+               e = der_match_tag_and_length(p, len, ASN1_C_CONTEXT, &enc_part_type, 3, &enc_part_datalen, &l);
+               if (e == 0 && enc_part_type != CONS) {
+                   e = ASN1_BAD_ID;
+               }
                if (e)
-                   return e;
-               else {
-                   p += l;
-                   len -= l;
-                   ret += l;
-                   e = der_get_length(p, len, &newlen, &l);
-                   FORW;
-                   {
-                       int dce_fix;
-                       oldlen = len;
-                       if ((dce_fix = fix_dce(newlen, &len)) < 0)
-                           return ASN1_BAD_FORMAT;
-                       e = decode_EncryptedData(p, len, &(data)->enc_part,
-                                                &l);
-                       FORW;
-                       if (dce_fix) {
-                           e = der_match_tag_and_length(p, len,
-                                                        (Der_class) 0,
-                                                        (Der_type) 0, 0,
-                                                        &reallen, &l);
-                           FORW;
-                       } else
-                           len = oldlen - newlen;
-                   }
+                   goto fail;
+               p += l;
+               len -= l;
+               ret += l;
+               enc_part_oldlen = len;
+               if (enc_part_datalen > len) {
+                   e = ASN1_OVERRUN;
+                   goto fail;
                }
+               len = enc_part_datalen;
+               e = decode_EncryptedData(p, len, &(data)->enc_part, &l);
+               if (e)
+                   goto fail;
+               p += l;
+               len -= l;
+               ret += l;
+               len = enc_part_oldlen - enc_part_datalen;
            }
-           if (dce_fix) {
-               e = der_match_tag_and_length(p, len, (Der_class) 0,
-                                            (Der_type) 0, 0, &reallen, &l);
-               FORW;
-           }
-       }
-       if (dce_fix) {
-           e = der_match_tag_and_length(p, len, (Der_class) 0, (Der_type) 0,
-                                        0, &reallen, &l);
-           FORW;
+           len = Top_Tag_oldlen - Top_Tag_datalen;
        }
+       len = Top_oldlen - Top_datalen;
     }
     if (size)
        *size = ret;
     return 0;
-  fail:
+fail:
     free_Ticket(data);
     return e;
 }
@@ -232,6 +381,7 @@ decode_Ticket(const unsigned char *p, size_t len, Ticket * data,
 void
 free_Ticket(Ticket * data)
 {
+    free_krb5int32(&(data)->tkt_vno);
     free_Realm(&(data)->realm);
     free_PrincipalName(&(data)->sname);
     free_EncryptedData(&(data)->enc_part);
@@ -242,48 +392,59 @@ length_Ticket(const Ticket * data)
 {
     size_t ret = 0;
     {
-       int oldret = ret;
+       size_t Top_tag_tag_oldret = ret;
        ret = 0;
-       ret += length_integer(&(data)->tkt_vno);
-       ret += 1 + length_len(ret) + oldret;
+       ret += length_krb5int32(&(data)->tkt_vno);
+       ret += 1 + der_length_len(ret);
+       ret += Top_tag_tag_oldret;
     }
     {
-       int oldret = ret;
+       size_t Top_tag_tag_oldret = ret;
        ret = 0;
        ret += length_Realm(&(data)->realm);
-       ret += 1 + length_len(ret) + oldret;
+       ret += 1 + der_length_len(ret);
+       ret += Top_tag_tag_oldret;
     }
     {
-       int oldret = ret;
+       size_t Top_tag_tag_oldret = ret;
        ret = 0;
        ret += length_PrincipalName(&(data)->sname);
-       ret += 1 + length_len(ret) + oldret;
+       ret += 1 + der_length_len(ret);
+       ret += Top_tag_tag_oldret;
     }
     {
-       int oldret = ret;
+       size_t Top_tag_tag_oldret = ret;
        ret = 0;
        ret += length_EncryptedData(&(data)->enc_part);
-       ret += 1 + length_len(ret) + oldret;
+       ret += 1 + der_length_len(ret);
+       ret += Top_tag_tag_oldret;
     }
-    ret += 1 + length_len(ret);
-    ret += 1 + length_len(ret);
+    ret += 1 + der_length_len(ret);
+    ret += 1 + der_length_len(ret);
     return ret;
 }
 
 int
 copy_Ticket(const Ticket * from, Ticket * to)
 {
-    *(&(to)->tkt_vno) = *(&(from)->tkt_vno);
+    memset(to, 0, sizeof(*to));
+    if (copy_krb5int32(&(from)->tkt_vno, &(to)->tkt_vno))
+       goto fail;
     if (copy_Realm(&(from)->realm, &(to)->realm))
-       return ENOMEM;
+       goto fail;
     if (copy_PrincipalName(&(from)->sname, &(to)->sname))
-       return ENOMEM;
+       goto fail;
     if (copy_EncryptedData(&(from)->enc_part, &(to)->enc_part))
-       return ENOMEM;
+       goto fail;
     return 0;
+fail:
+    free_Ticket(to);
+    return ENOMEM;
 }
 
-/* Generated from /home/lha/src/cvs/heimdal/lib/asn1/k5.asn1 */
+
+
+/* Generated from ./krb5.asn1 */
 /* Do not edit */
 
 #include <stdio.h>
@@ -291,171 +452,463 @@ copy_Ticket(const Ticket * from, Ticket * to)
 #include <time.h>
 #include <string.h>
 #include <errno.h>
+#include <limits.h>
 #include <asn1_err.h>
 
-#define BACK if (e) return e; p -= l; len -= l; ret += l
-
 int
-encode_EncryptedData(unsigned char *p, size_t len, const EncryptedData * data,
-                    size_t * size)
+encode_AuthorizationDataElement(unsigned char *p, size_t len, const AuthorizationDataElement * data, size_t * size)
 {
     size_t ret = 0;
     size_t l;
     int i, e;
 
     i = 0;
+/* ad-data */
     {
-       int oldret = ret;
+       size_t Top_tag_oldret = ret;
        ret = 0;
-       e = encode_octet_string(p, len, &(data)->cipher, &l);
-       BACK;
-       e = der_put_length_and_tag(p, len, ret, Der_CONTEXT, CONS, 2, &l);
-       BACK;
-       ret += oldret;
-    }
-    if ((data)->kvno) {
-       int oldret = ret;
-       ret = 0;
-       e = encode_integer(p, len, (data)->kvno, &l);
-       BACK;
-       e = der_put_length_and_tag(p, len, ret, Der_CONTEXT, CONS, 1, &l);
-       BACK;
-       ret += oldret;
-    }
+       e = der_put_octet_string(p, len, &(data)->ad_data, &l);
+       if (e)
+           return e;
+       p -= l;
+       len -= l;
+       ret += l;
+
+       e = der_put_length_and_tag(p, len, ret, ASN1_C_UNIV, PRIM, UT_OctetString, &l);
+       if (e)
+           return e;
+       p -= l;
+       len -= l;
+       ret += l;
+
+       e = der_put_length_and_tag(p, len, ret, ASN1_C_CONTEXT, CONS, 1, &l);
+       if (e)
+           return e;
+       p -= l;
+       len -= l;
+       ret += l;
+
+       ret += Top_tag_oldret;
+    }
+/* ad-type */
     {
-       int oldret = ret;
+       size_t Top_tag_oldret = ret;
        ret = 0;
-       e = encode_ENCTYPE(p, len, &(data)->etype, &l);
-       BACK;
-       e = der_put_length_and_tag(p, len, ret, Der_CONTEXT, CONS, 0, &l);
-       BACK;
-       ret += oldret;
-    }
-    e = der_put_length_and_tag(p, len, ret, UNIV, CONS, UT_Sequence, &l);
-    BACK;
+       e = encode_krb5int32(p, len, &(data)->ad_type, &l);
+       if (e)
+           return e;
+       p -= l;
+       len -= l;
+       ret += l;
+
+       e = der_put_length_and_tag(p, len, ret, ASN1_C_CONTEXT, CONS, 0, &l);
+       if (e)
+           return e;
+       p -= l;
+       len -= l;
+       ret += l;
+
+       ret += Top_tag_oldret;
+    }
+    e = der_put_length_and_tag(p, len, ret, ASN1_C_UNIV, CONS, UT_Sequence, &l);
+    if (e)
+       return e;
+    p -= l;
+    len -= l;
+    ret += l;
+
     *size = ret;
     return 0;
 }
 
-#define FORW if(e) goto fail; p += l; len -= l; ret += l
-
 int
-decode_EncryptedData(const unsigned char *p, size_t len, EncryptedData * data,
-                    size_t * size)
+decode_AuthorizationDataElement(const unsigned char *p, size_t len, AuthorizationDataElement * data, size_t * size)
 {
-    size_t ret = 0, reallen;
+    size_t ret = 0;
     size_t l;
     int e;
 
     memset(data, 0, sizeof(*data));
-    reallen = 0;
-    e = der_match_tag_and_length(p, len, UNIV, CONS, UT_Sequence, &reallen,
-                                &l);
-    FORW;
-    {
-       int dce_fix;
-       if ((dce_fix = fix_dce(reallen, &len)) < 0)
-           return ASN1_BAD_FORMAT;
+    {
+       size_t Top_datalen, Top_oldlen;
+       Der_type Top_type;
+       e = der_match_tag_and_length(p, len, ASN1_C_UNIV, &Top_type, UT_Sequence, &Top_datalen, &l);
+       if (e == 0 && Top_type != CONS) {
+           e = ASN1_BAD_ID;
+       }
+       if (e)
+           goto fail;
+       p += l;
+       len -= l;
+       ret += l;
+       Top_oldlen = len;
+       if (Top_datalen > len) {
+           e = ASN1_OVERRUN;
+           goto fail;
+       }
+       len = Top_datalen;
        {
-           size_t newlen, oldlen;
-
-           e = der_match_tag(p, len, Der_CONTEXT, CONS, 0, &l);
+           size_t ad_type_datalen, ad_type_oldlen;
+           Der_type ad_type_type;
+           e = der_match_tag_and_length(p, len, ASN1_C_CONTEXT, &ad_type_type, 0, &ad_type_datalen, &l);
+           if (e == 0 && ad_type_type != CONS) {
+               e = ASN1_BAD_ID;
+           }
            if (e)
-               return e;
-           else {
+               goto fail;
+           p += l;
+           len -= l;
+           ret += l;
+           ad_type_oldlen = len;
+           if (ad_type_datalen > len) {
+               e = ASN1_OVERRUN;
+               goto fail;
+           }
+           len = ad_type_datalen;
+           e = decode_krb5int32(p, len, &(data)->ad_type, &l);
+           if (e)
+               goto fail;
+           p += l;
+           len -= l;
+           ret += l;
+           len = ad_type_oldlen - ad_type_datalen;
+       }
+       {
+           size_t ad_data_datalen, ad_data_oldlen;
+           Der_type ad_data_type;
+           e = der_match_tag_and_length(p, len, ASN1_C_CONTEXT, &ad_data_type, 1, &ad_data_datalen, &l);
+           if (e == 0 && ad_data_type != CONS) {
+               e = ASN1_BAD_ID;
+           }
+           if (e)
+               goto fail;
+           p += l;
+           len -= l;
+           ret += l;
+           ad_data_oldlen = len;
+           if (ad_data_datalen > len) {
+               e = ASN1_OVERRUN;
+               goto fail;
+           }
+           len = ad_data_datalen;
+           {
+               size_t ad_data_Tag_datalen, ad_data_Tag_oldlen;
+               Der_type ad_data_Tag_type;
+               e = der_match_tag_and_length(p, len, ASN1_C_UNIV, &ad_data_Tag_type, UT_OctetString, &ad_data_Tag_datalen, &l);
+               if (e == 0 && ad_data_Tag_type != PRIM) {
+                   e = ASN1_BAD_ID;
+               }
+               if (e)
+                   goto fail;
                p += l;
                len -= l;
                ret += l;
-               e = der_get_length(p, len, &newlen, &l);
-               FORW;
-               {
-                   int dce_fix;
-                   oldlen = len;
-                   if ((dce_fix = fix_dce(newlen, &len)) < 0)
-                       return ASN1_BAD_FORMAT;
-                   e = decode_ENCTYPE(p, len, &(data)->etype, &l);
-                   FORW;
-                   if (dce_fix) {
-                       e = der_match_tag_and_length(p, len, (Der_class) 0,
-                                                    (Der_type) 0, 0,
-                                                    &reallen, &l);
-                       FORW;
-                   } else
-                       len = oldlen - newlen;
+               ad_data_Tag_oldlen = len;
+               if (ad_data_Tag_datalen > len) {
+                   e = ASN1_OVERRUN;
+                   goto fail;
                }
+               len = ad_data_Tag_datalen;
+               e = der_get_octet_string(p, len, &(data)->ad_data, &l);
+               if (e)
+                   goto fail;
+               p += l;
+               len -= l;
+               ret += l;
+               len = ad_data_Tag_oldlen - ad_data_Tag_datalen;
            }
+           len = ad_data_oldlen - ad_data_datalen;
        }
-       {
-           size_t newlen, oldlen;
+       len = Top_oldlen - Top_datalen;
+    }
+    if (size)
+       *size = ret;
+    return 0;
+fail:
+    free_AuthorizationDataElement(data);
+    return e;
+}
+
+void
+free_AuthorizationDataElement(AuthorizationDataElement * data)
+{
+    free_krb5int32(&(data)->ad_type);
+    der_free_octet_string(&(data)->ad_data);
+}
 
-           e = der_match_tag(p, len, Der_CONTEXT, CONS, 1, &l);
+size_t
+length_AuthorizationDataElement(const AuthorizationDataElement * data)
+{
+    size_t ret = 0;
+    {
+       size_t Top_tag_oldret = ret;
+       ret = 0;
+       ret += length_krb5int32(&(data)->ad_type);
+       ret += 1 + der_length_len(ret);
+       ret += Top_tag_oldret;
+    }
+    {
+       size_t Top_tag_oldret = ret;
+       ret = 0;
+       ret += der_length_octet_string(&(data)->ad_data);
+       ret += 1 + der_length_len(ret);
+       ret += 1 + der_length_len(ret);
+       ret += Top_tag_oldret;
+    }
+    ret += 1 + der_length_len(ret);
+    return ret;
+}
+
+int
+copy_AuthorizationDataElement(const AuthorizationDataElement * from, AuthorizationDataElement * to)
+{
+    memset(to, 0, sizeof(*to));
+    if (copy_krb5int32(&(from)->ad_type, &(to)->ad_type))
+       goto fail;
+    if (der_copy_octet_string(&(from)->ad_data, &(to)->ad_data))
+       goto fail;
+    return 0;
+fail:
+    free_AuthorizationDataElement(to);
+    return ENOMEM;
+}
+
+
+
+/* Generated from ./krb5.asn1 */
+/* Do not edit */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <string.h>
+#include <errno.h>
+#include <limits.h>
+#include <asn1_err.h>
+
+int
+encode_EncryptedData(unsigned char *p, size_t len, const EncryptedData * data, size_t * size)
+{
+    size_t ret = 0;
+    size_t l;
+    int i, e;
+
+    i = 0;
+/* cipher */
+    {
+       size_t Top_tag_oldret = ret;
+       ret = 0;
+       e = der_put_octet_string(p, len, &(data)->cipher, &l);
+       if (e)
+           return e;
+       p -= l;
+       len -= l;
+       ret += l;
+
+       e = der_put_length_and_tag(p, len, ret, ASN1_C_UNIV, PRIM, UT_OctetString, &l);
+       if (e)
+           return e;
+       p -= l;
+       len -= l;
+       ret += l;
+
+       e = der_put_length_and_tag(p, len, ret, ASN1_C_CONTEXT, CONS, 2, &l);
+       if (e)
+           return e;
+       p -= l;
+       len -= l;
+       ret += l;
+
+       ret += Top_tag_oldret;
+    }
+/* kvno */
+    if ((data)->kvno) {
+       size_t Top_tag_oldret = ret;
+       ret = 0;
+       e = encode_krb5int32(p, len, (data)->kvno, &l);
+       if (e)
+           return e;
+       p -= l;
+       len -= l;
+       ret += l;
+
+       e = der_put_length_and_tag(p, len, ret, ASN1_C_CONTEXT, CONS, 1, &l);
+       if (e)
+           return e;
+       p -= l;
+       len -= l;
+       ret += l;
+
+       ret += Top_tag_oldret;
+    }
+/* etype */
+    {
+       size_t Top_tag_oldret = ret;
+       ret = 0;
+       e = encode_ENCTYPE(p, len, &(data)->etype, &l);
+       if (e)
+           return e;
+       p -= l;
+       len -= l;
+       ret += l;
+
+       e = der_put_length_and_tag(p, len, ret, ASN1_C_CONTEXT, CONS, 0, &l);
+       if (e)
+           return e;
+       p -= l;
+       len -= l;
+       ret += l;
+
+       ret += Top_tag_oldret;
+    }
+    e = der_put_length_and_tag(p, len, ret, ASN1_C_UNIV, CONS, UT_Sequence, &l);
+    if (e)
+       return e;
+    p -= l;
+    len -= l;
+    ret += l;
+
+    *size = ret;
+    return 0;
+}
+
+int
+decode_EncryptedData(const unsigned char *p, size_t len, EncryptedData * data, size_t * size)
+{
+    size_t ret = 0;
+    size_t l;
+    int e;
+
+    memset(data, 0, sizeof(*data));
+    {
+       size_t Top_datalen, Top_oldlen;
+       Der_type Top_type;
+       e = der_match_tag_and_length(p, len, ASN1_C_UNIV, &Top_type, UT_Sequence, &Top_datalen, &l);
+       if (e == 0 && Top_type != CONS) {
+           e = ASN1_BAD_ID;
+       }
+       if (e)
+           goto fail;
+       p += l;
+       len -= l;
+       ret += l;
+       Top_oldlen = len;
+       if (Top_datalen > len) {
+           e = ASN1_OVERRUN;
+           goto fail;
+       }
+       len = Top_datalen;
+       {
+           size_t etype_datalen, etype_oldlen;
+           Der_type etype_type;
+           e = der_match_tag_and_length(p, len, ASN1_C_CONTEXT, &etype_type, 0, &etype_datalen, &l);
+           if (e == 0 && etype_type != CONS) {
+               e = ASN1_BAD_ID;
+           }
            if (e)
+               goto fail;
+           p += l;
+           len -= l;
+           ret += l;
+           etype_oldlen = len;
+           if (etype_datalen > len) {
+               e = ASN1_OVERRUN;
+               goto fail;
+           }
+           len = etype_datalen;
+           e = decode_ENCTYPE(p, len, &(data)->etype, &l);
+           if (e)
+               goto fail;
+           p += l;
+           len -= l;
+           ret += l;
+           len = etype_oldlen - etype_datalen;
+       }
+       {
+           size_t kvno_datalen, kvno_oldlen;
+           Der_type kvno_type;
+           e = der_match_tag_and_length(p, len, ASN1_C_CONTEXT, &kvno_type, 1, &kvno_datalen, &l);
+           if (e == 0 && kvno_type != CONS) {
+               e = ASN1_BAD_ID;
+           }
+           if (e) {
                (data)->kvno = NULL;
-           else {
+           } else {
+               (data)->kvno = calloc(1, sizeof(*(data)->kvno));
+               if ((data)->kvno == NULL) {
+                   e = ENOMEM;
+                   goto fail;
+               }
                p += l;
                len -= l;
                ret += l;
-               e = der_get_length(p, len, &newlen, &l);
-               FORW;
-               {
-                   int dce_fix;
-                   oldlen = len;
-                   if ((dce_fix = fix_dce(newlen, &len)) < 0)
-                       return ASN1_BAD_FORMAT;
-                   (data)->kvno = malloc(sizeof(*(data)->kvno));
-                   if ((data)->kvno == NULL)
-                       return ENOMEM;
-                   e = decode_integer(p, len, (data)->kvno, &l);
-                   FORW;
-                   if (dce_fix) {
-                       e = der_match_tag_and_length(p, len, (Der_class) 0,
-                                                    (Der_type) 0, 0,
-                                                    &reallen, &l);
-                       FORW;
-                   } else
-                       len = oldlen - newlen;
+               kvno_oldlen = len;
+               if (kvno_datalen > len) {
+                   e = ASN1_OVERRUN;
+                   goto fail;
                }
+               len = kvno_datalen;
+               e = decode_krb5int32(p, len, (data)->kvno, &l);
+               if (e)
+                   goto fail;
+               p += l;
+               len -= l;
+               ret += l;
+               len = kvno_oldlen - kvno_datalen;
            }
        }
        {
-           size_t newlen, oldlen;
-
-           e = der_match_tag(p, len, Der_CONTEXT, CONS, 2, &l);
+           size_t cipher_datalen, cipher_oldlen;
+           Der_type cipher_type;
+           e = der_match_tag_and_length(p, len, ASN1_C_CONTEXT, &cipher_type, 2, &cipher_datalen, &l);
+           if (e == 0 && cipher_type != CONS) {
+               e = ASN1_BAD_ID;
+           }
            if (e)
-               return e;
-           else {
+               goto fail;
+           p += l;
+           len -= l;
+           ret += l;
+           cipher_oldlen = len;
+           if (cipher_datalen > len) {
+               e = ASN1_OVERRUN;
+               goto fail;
+           }
+           len = cipher_datalen;
+           {
+               size_t cipher_Tag_datalen, cipher_Tag_oldlen;
+               Der_type cipher_Tag_type;
+               e = der_match_tag_and_length(p, len, ASN1_C_UNIV, &cipher_Tag_type, UT_OctetString, &cipher_Tag_datalen, &l);
+               if (e == 0 && cipher_Tag_type != PRIM) {
+                   e = ASN1_BAD_ID;
+               }
+               if (e)
+                   goto fail;
                p += l;
                len -= l;
                ret += l;
-               e = der_get_length(p, len, &newlen, &l);
-               FORW;
-               {
-                   int dce_fix;
-                   oldlen = len;
-                   if ((dce_fix = fix_dce(newlen, &len)) < 0)
-                       return ASN1_BAD_FORMAT;
-                   e = decode_octet_string(p, len, &(data)->cipher, &l);
-                   FORW;
-                   if (dce_fix) {
-                       e = der_match_tag_and_length(p, len, (Der_class) 0,
-                                                    (Der_type) 0, 0,
-                                                    &reallen, &l);
-                       FORW;
-                   } else
-                       len = oldlen - newlen;
+               cipher_Tag_oldlen = len;
+               if (cipher_Tag_datalen > len) {
+                   e = ASN1_OVERRUN;
+                   goto fail;
                }
+               len = cipher_Tag_datalen;
+               e = der_get_octet_string(p, len, &(data)->cipher, &l);
+               if (e)
+                   goto fail;
+               p += l;
+               len -= l;
+               ret += l;
+               len = cipher_Tag_oldlen - cipher_Tag_datalen;
            }
+           len = cipher_oldlen - cipher_datalen;
        }
-       if (dce_fix) {
-           e = der_match_tag_and_length(p, len, (Der_class) 0, (Der_type) 0,
-                                        0, &reallen, &l);
-           FORW;
-       }
+       len = Top_oldlen - Top_datalen;
     }
     if (size)
        *size = ret;
     return 0;
-  fail:
+fail:
     free_EncryptedData(data);
     return e;
 }
@@ -465,9 +918,11 @@ free_EncryptedData(EncryptedData * data)
 {
     free_ENCTYPE(&(data)->etype);
     if ((data)->kvno) {
+       free_krb5int32((data)->kvno);
        free((data)->kvno);
+       (data)->kvno = NULL;
     }
-    free_octet_string(&(data)->cipher);
+    der_free_octet_string(&(data)->cipher);
 }
 
 size_t
@@ -475,45 +930,55 @@ length_EncryptedData(const EncryptedData * data)
 {
     size_t ret = 0;
     {
-       int oldret = ret;
+       size_t Top_tag_oldret = ret;
        ret = 0;
        ret += length_ENCTYPE(&(data)->etype);
-       ret += 1 + length_len(ret) + oldret;
+       ret += 1 + der_length_len(ret);
+       ret += Top_tag_oldret;
     }
     if ((data)->kvno) {
-       int oldret = ret;
+       size_t Top_tag_oldret = ret;
        ret = 0;
-       ret += length_integer((data)->kvno);
-       ret += 1 + length_len(ret) + oldret;
-    }
-    {
-       int oldret = ret;
+       ret += length_krb5int32((data)->kvno);
+       ret += 1 + der_length_len(ret);
+       ret += Top_tag_oldret;
+    } {
+       size_t Top_tag_oldret = ret;
        ret = 0;
-       ret += length_octet_string(&(data)->cipher);
-       ret += 1 + length_len(ret) + oldret;
+       ret += der_length_octet_string(&(data)->cipher);
+       ret += 1 + der_length_len(ret);
+       ret += 1 + der_length_len(ret);
+       ret += Top_tag_oldret;
     }
-    ret += 1 + length_len(ret);
+    ret += 1 + der_length_len(ret);
     return ret;
 }
 
 int
 copy_EncryptedData(const EncryptedData * from, EncryptedData * to)
 {
+    memset(to, 0, sizeof(*to));
     if (copy_ENCTYPE(&(from)->etype, &(to)->etype))
-       return ENOMEM;
+       goto fail;
     if ((from)->kvno) {
        (to)->kvno = malloc(sizeof(*(to)->kvno));
        if ((to)->kvno == NULL)
-           return ENOMEM;
-       *((to)->kvno) = *((from)->kvno);
+           goto fail;
+       if (copy_krb5int32((from)->kvno, (to)->kvno))
+           goto fail;
     } else
        (to)->kvno = NULL;
-    if (copy_octet_string(&(from)->cipher, &(to)->cipher))
-       return ENOMEM;
+    if (der_copy_octet_string(&(from)->cipher, &(to)->cipher))
+       goto fail;
     return 0;
+fail:
+    free_EncryptedData(to);
+    return ENOMEM;
 }
 
-/* Generated from /home/lha/src/cvs/heimdal/lib/asn1/k5.asn1 */
+
+
+/* Generated from ./krb5.asn1 */
 /* Do not edit */
 
 #include <stdio.h>
@@ -521,165 +986,237 @@ copy_EncryptedData(const EncryptedData * from, EncryptedData * to)
 #include <time.h>
 #include <string.h>
 #include <errno.h>
+#include <limits.h>
 #include <asn1_err.h>
 
-#define BACK if (e) return e; p -= l; len -= l; ret += l
-
 int
-encode_PrincipalName(unsigned char *p, size_t len, const PrincipalName * data,
-                    size_t * size)
+encode_PrincipalName(unsigned char *p, size_t len, const PrincipalName * data, size_t * size)
 {
     size_t ret = 0;
     size_t l;
     int i, e;
 
     i = 0;
+/* name-string */
     {
-       int oldret = ret;
+       size_t Top_tag_oldret = ret;
        ret = 0;
        for (i = (&(data)->name_string)->len - 1; i >= 0; --i) {
-           int oldret = ret;
+           size_t name_string_tag_tag_for_oldret = ret;
            ret = 0;
-           e = encode_general_string(p, len, &(&(data)->name_string)->val[i],
-                                     &l);
-           BACK;
-           ret += oldret;
+           e = der_put_general_string(p, len, &(&(data)->name_string)->val[i], &l);
+           if (e)
+               return e;
+           p -= l;
+           len -= l;
+           ret += l;
+
+           e = der_put_length_and_tag(p, len, ret, ASN1_C_UNIV, PRIM, UT_GeneralString, &l);
+           if (e)
+               return e;
+           p -= l;
+           len -= l;
+           ret += l;
+
+           ret += name_string_tag_tag_for_oldret;
        }
-       e = der_put_length_and_tag(p, len, ret, UNIV, CONS, UT_Sequence, &l);
-       BACK;
-       e = der_put_length_and_tag(p, len, ret, Der_CONTEXT, CONS, 1, &l);
-       BACK;
-       ret += oldret;
-    }
+       e = der_put_length_and_tag(p, len, ret, ASN1_C_UNIV, CONS, UT_Sequence, &l);
+       if (e)
+           return e;
+       p -= l;
+       len -= l;
+       ret += l;
+
+       e = der_put_length_and_tag(p, len, ret, ASN1_C_CONTEXT, CONS, 1, &l);
+       if (e)
+           return e;
+       p -= l;
+       len -= l;
+       ret += l;
+
+       ret += Top_tag_oldret;
+    }
+/* name-type */
     {
-       int oldret = ret;
+       size_t Top_tag_oldret = ret;
        ret = 0;
        e = encode_NAME_TYPE(p, len, &(data)->name_type, &l);
-       BACK;
-       e = der_put_length_and_tag(p, len, ret, Der_CONTEXT, CONS, 0, &l);
-       BACK;
-       ret += oldret;
-    }
-    e = der_put_length_and_tag(p, len, ret, UNIV, CONS, UT_Sequence, &l);
-    BACK;
+       if (e)
+           return e;
+       p -= l;
+       len -= l;
+       ret += l;
+
+       e = der_put_length_and_tag(p, len, ret, ASN1_C_CONTEXT, CONS, 0, &l);
+       if (e)
+           return e;
+       p -= l;
+       len -= l;
+       ret += l;
+
+       ret += Top_tag_oldret;
+    }
+    e = der_put_length_and_tag(p, len, ret, ASN1_C_UNIV, CONS, UT_Sequence, &l);
+    if (e)
+       return e;
+    p -= l;
+    len -= l;
+    ret += l;
+
     *size = ret;
     return 0;
 }
 
-#define FORW if(e) goto fail; p += l; len -= l; ret += l
-
 int
-decode_PrincipalName(const unsigned char *p, size_t len, PrincipalName * data,
-                    size_t * size)
+decode_PrincipalName(const unsigned char *p, size_t len, PrincipalName * data, size_t * size)
 {
-    size_t ret = 0, reallen;
+    size_t ret = 0;
     size_t l;
     int e;
 
     memset(data, 0, sizeof(*data));
-    reallen = 0;
-    e = der_match_tag_and_length(p, len, UNIV, CONS, UT_Sequence, &reallen,
-                                &l);
-    FORW;
-    {
-       int dce_fix;
-       if ((dce_fix = fix_dce(reallen, &len)) < 0)
-           return ASN1_BAD_FORMAT;
+    {
+       size_t Top_datalen, Top_oldlen;
+       Der_type Top_type;
+       e = der_match_tag_and_length(p, len, ASN1_C_UNIV, &Top_type, UT_Sequence, &Top_datalen, &l);
+       if (e == 0 && Top_type != CONS) {
+           e = ASN1_BAD_ID;
+       }
+       if (e)
+           goto fail;
+       p += l;
+       len -= l;
+       ret += l;
+       Top_oldlen = len;
+       if (Top_datalen > len) {
+           e = ASN1_OVERRUN;
+           goto fail;
+       }
+       len = Top_datalen;
        {
-           size_t newlen, oldlen;
-
-           e = der_match_tag(p, len, Der_CONTEXT, CONS, 0, &l);
+           size_t name_type_datalen, name_type_oldlen;
+           Der_type name_type_type;
+           e = der_match_tag_and_length(p, len, ASN1_C_CONTEXT, &name_type_type, 0, &name_type_datalen, &l);
+           if (e == 0 && name_type_type != CONS) {
+               e = ASN1_BAD_ID;
+           }
            if (e)
-               return e;
-           else {
-               p += l;
-               len -= l;
-               ret += l;
-               e = der_get_length(p, len, &newlen, &l);
-               FORW;
-               {
-                   int dce_fix;
-                   oldlen = len;
-                   if ((dce_fix = fix_dce(newlen, &len)) < 0)
-                       return ASN1_BAD_FORMAT;
-                   e = decode_NAME_TYPE(p, len, &(data)->name_type, &l);
-                   FORW;
-                   if (dce_fix) {
-                       e = der_match_tag_and_length(p, len, (Der_class) 0,
-                                                    (Der_type) 0, 0,
-                                                    &reallen, &l);
-                       FORW;
-                   } else
-                       len = oldlen - newlen;
-               }
+               goto fail;
+           p += l;
+           len -= l;
+           ret += l;
+           name_type_oldlen = len;
+           if (name_type_datalen > len) {
+               e = ASN1_OVERRUN;
+               goto fail;
            }
+           len = name_type_datalen;
+           e = decode_NAME_TYPE(p, len, &(data)->name_type, &l);
+           if (e)
+               goto fail;
+           p += l;
+           len -= l;
+           ret += l;
+           len = name_type_oldlen - name_type_datalen;
        }
        {
-           size_t newlen, oldlen;
-
-           e = der_match_tag(p, len, Der_CONTEXT, CONS, 1, &l);
+           size_t name_string_datalen, name_string_oldlen;
+           Der_type name_string_type;
+           e = der_match_tag_and_length(p, len, ASN1_C_CONTEXT, &name_string_type, 1, &name_string_datalen, &l);
+           if (e == 0 && name_string_type != CONS) {
+               e = ASN1_BAD_ID;
+           }
            if (e)
-               return e;
-           else {
+               goto fail;
+           p += l;
+           len -= l;
+           ret += l;
+           name_string_oldlen = len;
+           if (name_string_datalen > len) {
+               e = ASN1_OVERRUN;
+               goto fail;
+           }
+           len = name_string_datalen;
+           {
+               size_t name_string_Tag_datalen, name_string_Tag_oldlen;
+               Der_type name_string_Tag_type;
+               e = der_match_tag_and_length(p, len, ASN1_C_UNIV, &name_string_Tag_type, UT_Sequence, &name_string_Tag_datalen, &l);
+               if (e == 0 && name_string_Tag_type != CONS) {
+                   e = ASN1_BAD_ID;
+               }
+               if (e)
+                   goto fail;
                p += l;
                len -= l;
                ret += l;
-               e = der_get_length(p, len, &newlen, &l);
-               FORW;
+               name_string_Tag_oldlen = len;
+               if (name_string_Tag_datalen > len) {
+                   e = ASN1_OVERRUN;
+                   goto fail;
+               }
+               len = name_string_Tag_datalen;
                {
-                   int dce_fix;
-                   oldlen = len;
-                   if ((dce_fix = fix_dce(newlen, &len)) < 0)
-                       return ASN1_BAD_FORMAT;
-                   e = der_match_tag_and_length(p, len, UNIV, CONS,
-                                                UT_Sequence, &reallen, &l);
-                   FORW;
-                   if (len < reallen)
-                       return ASN1_OVERRUN;
-                   len = reallen;
-                   {
-                       size_t origlen = len;
-                       int oldret = ret;
-                       ret = 0;
-                       (&(data)->name_string)->len = 0;
-                       (&(data)->name_string)->val = NULL;
-                       while (ret < origlen) {
-                           (&(data)->name_string)->len++;
-                           (&(data)->name_string)->val =
-                               realloc((&(data)->name_string)->val,
-                                       sizeof(*((&(data)->name_string)->val))
-                                       * (&(data)->name_string)->len);
-                           e = decode_general_string(p, len,
-                                                     &(&(data)->
-                                                       name_string)->
-                                                     val[(&(data)->
-                                                          name_string)->len -
-                                                         1], &l);
-                           FORW;
-                           len = origlen - ret;
+                   size_t name_string_Tag_Tag_origlen = len;
+                   size_t name_string_Tag_Tag_oldret = ret;
+                   size_t name_string_Tag_Tag_olen = 0;
+                   void *name_string_Tag_Tag_tmp;
+                   ret = 0;
+                   (&(data)->name_string)->len = 0;
+                   (&(data)->name_string)->val = NULL;
+                   while (ret < name_string_Tag_Tag_origlen) {
+                       size_t name_string_Tag_Tag_nlen = name_string_Tag_Tag_olen + sizeof(*((&(data)->name_string)->val));
+                       if (name_string_Tag_Tag_olen > name_string_Tag_Tag_nlen) {
+                           e = ASN1_OVERFLOW;
+                           goto fail;
+                       }
+                       name_string_Tag_Tag_olen = name_string_Tag_Tag_nlen;
+                       name_string_Tag_Tag_tmp = realloc((&(data)->name_string)->val, name_string_Tag_Tag_olen);
+                       if (name_string_Tag_Tag_tmp == NULL) {
+                           e = ENOMEM;
+                           goto fail;
+                       }
+                       (&(data)->name_string)->val = name_string_Tag_Tag_tmp;
+                       {
+                           size_t name_string_Tag_Tag_s_of_datalen, name_string_Tag_Tag_s_of_oldlen;
+                           Der_type name_string_Tag_Tag_s_of_type;
+                           e = der_match_tag_and_length(p, len, ASN1_C_UNIV, &name_string_Tag_Tag_s_of_type, UT_GeneralString, &name_string_Tag_Tag_s_of_datalen, &l);
+                           if (e == 0 && name_string_Tag_Tag_s_of_type != PRIM) {
+                               e = ASN1_BAD_ID;
+                           }
+                           if (e)
+                               goto fail;
+                           p += l;
+                           len -= l;
+                           ret += l;
+                           name_string_Tag_Tag_s_of_oldlen = len;
+                           if (name_string_Tag_Tag_s_of_datalen > len) {
+                               e = ASN1_OVERRUN;
+                               goto fail;
+                           }
+                           len = name_string_Tag_Tag_s_of_datalen;
+                           e = der_get_general_string(p, len, &(&(data)->name_string)->val[(&(data)->name_string)->len], &l);
+                           if (e)
+                               goto fail;
+                           p += l;
+                           len -= l;
+                           ret += l;
+                           len = name_string_Tag_Tag_s_of_oldlen - name_string_Tag_Tag_s_of_datalen;
                        }
-                       ret += oldret;
+                       (&(data)->name_string)->len++;
+                       len = name_string_Tag_Tag_origlen - ret;
                    }
-                   if (dce_fix) {
-                       e = der_match_tag_and_length(p, len, (Der_class) 0,
-                                                    (Der_type) 0, 0,
-                                                    &reallen, &l);
-                       FORW;
-                   } else
-                       len = oldlen - newlen;
+                   ret += name_string_Tag_Tag_oldret;
                }
+               len = name_string_Tag_oldlen - name_string_Tag_datalen;
            }
+           len = name_string_oldlen - name_string_datalen;
        }
-       if (dce_fix) {
-           e = der_match_tag_and_length(p, len, (Der_class) 0, (Der_type) 0,
-                                        0, &reallen, &l);
-           FORW;
-       }
+       len = Top_oldlen - Top_datalen;
     }
     if (size)
        *size = ret;
     return 0;
-  fail:
+fail:
     free_PrincipalName(data);
     return e;
 }
@@ -689,11 +1226,11 @@ free_PrincipalName(PrincipalName * data)
 {
     free_NAME_TYPE(&(data)->name_type);
     while ((&(data)->name_string)->len) {
-       free_general_string(&(&(data)->name_string)->
-                           val[(&(data)->name_string)->len - 1]);
+       der_free_general_string(&(&(data)->name_string)->val[(&(data)->name_string)->len - 1]);
        (&(data)->name_string)->len--;
     }
     free((&(data)->name_string)->val);
+    (&(data)->name_string)->val = NULL;
 }
 
 size_t
@@ -701,51 +1238,57 @@ length_PrincipalName(const PrincipalName * data)
 {
     size_t ret = 0;
     {
-       int oldret = ret;
+       size_t Top_tag_oldret = ret;
        ret = 0;
        ret += length_NAME_TYPE(&(data)->name_type);
-       ret += 1 + length_len(ret) + oldret;
+       ret += 1 + der_length_len(ret);
+       ret += Top_tag_oldret;
     }
     {
-       int oldret = ret;
+       size_t Top_tag_oldret = ret;
        ret = 0;
        {
-           int oldret = ret;
+           int name_string_tag_tag_oldret = ret;
            int i;
            ret = 0;
            for (i = (&(data)->name_string)->len - 1; i >= 0; --i) {
-               ret += length_general_string(&(&(data)->name_string)->val[i]);
+               int name_string_tag_tag_for_oldret = ret;
+               ret = 0;
+               ret += der_length_general_string(&(&(data)->name_string)->val[i]);
+               ret += 1 + der_length_len(ret);
+               ret += name_string_tag_tag_for_oldret;
            }
-           ret += 1 + length_len(ret) + oldret;
+           ret += name_string_tag_tag_oldret;
        }
-       ret += 1 + length_len(ret) + oldret;
+       ret += 1 + der_length_len(ret);
+       ret += 1 + der_length_len(ret);
+       ret += Top_tag_oldret;
     }
-    ret += 1 + length_len(ret);
+    ret += 1 + der_length_len(ret);
     return ret;
 }
 
 int
 copy_PrincipalName(const PrincipalName * from, PrincipalName * to)
 {
+    memset(to, 0, sizeof(*to));
     if (copy_NAME_TYPE(&(from)->name_type, &(to)->name_type))
-       return ENOMEM;
-    if (((&(to)->name_string)->val =
-        malloc((&(from)->name_string)->len *
-               sizeof(*(&(to)->name_string)->val))) == NULL
-       && (&(from)->name_string)->len != 0)
-       return ENOMEM;
-    for ((&(to)->name_string)->len = 0;
-        (&(to)->name_string)->len < (&(from)->name_string)->len;
-        (&(to)->name_string)->len++) {
-       if (copy_general_string
-           (&(&(from)->name_string)->val[(&(to)->name_string)->len],
-            &(&(to)->name_string)->val[(&(to)->name_string)->len]))
-           return ENOMEM;
+       goto fail;
+    if (((&(to)->name_string)->val = malloc((&(from)->name_string)->len * sizeof(*(&(to)->name_string)->val))) == NULL && (&(from)->name_string)->len != 0)
+       goto fail;
+    for ((&(to)->name_string)->len = 0; (&(to)->name_string)->len < (&(from)->name_string)->len; (&(to)->name_string)->len++) {
+       if (der_copy_general_string(&(&(from)->name_string)->val[(&(to)->name_string)->len], &(&(to)->name_string)->val[(&(to)->name_string)->len]))
+           goto fail;
     }
     return 0;
+fail:
+    free_PrincipalName(to);
+    return ENOMEM;
 }
 
-/* Generated from /home/lha/src/cvs/heimdal/lib/asn1/k5.asn1 */
+
+
+/* Generated from ./krb5.asn1 */
 /* Do not edit */
 
 #include <stdio.h>
@@ -753,13 +1296,11 @@ copy_PrincipalName(const PrincipalName * from, PrincipalName * to)
 #include <time.h>
 #include <string.h>
 #include <errno.h>
+#include <limits.h>
 #include <asn1_err.h>
 
-#define BACK if (e) return e; p -= l; len -= l; ret += l
-
 int
-encode_HostAddresses(unsigned char *p, size_t len, const HostAddresses * data,
-                    size_t * size)
+encode_HostAddresses(unsigned char *p, size_t len, const HostAddresses * data, size_t * size)
 {
     size_t ret = 0;
     size_t l;
@@ -767,56 +1308,92 @@ encode_HostAddresses(unsigned char *p, size_t len, const HostAddresses * data,
 
     i = 0;
     for (i = (data)->len - 1; i >= 0; --i) {
-       int oldret = ret;
+       size_t Top_tag_for_oldret = ret;
        ret = 0;
        e = encode_HostAddress(p, len, &(data)->val[i], &l);
-       BACK;
-       ret += oldret;
+       if (e)
+           return e;
+       p -= l;
+       len -= l;
+       ret += l;
+
+       ret += Top_tag_for_oldret;
     }
-    e = der_put_length_and_tag(p, len, ret, UNIV, CONS, UT_Sequence, &l);
-    BACK;
+    e = der_put_length_and_tag(p, len, ret, ASN1_C_UNIV, CONS, UT_Sequence, &l);
+    if (e)
+       return e;
+    p -= l;
+    len -= l;
+    ret += l;
+
     *size = ret;
     return 0;
 }
 
-#define FORW if(e) goto fail; p += l; len -= l; ret += l
-
 int
-decode_HostAddresses(const unsigned char *p, size_t len, HostAddresses * data,
-                    size_t * size)
+decode_HostAddresses(const unsigned char *p, size_t len, HostAddresses * data, size_t * size)
 {
-    size_t ret = 0, reallen;
+    size_t ret = 0;
     size_t l;
     int e;
 
     memset(data, 0, sizeof(*data));
-    reallen = 0;
-    e = der_match_tag_and_length(p, len, UNIV, CONS, UT_Sequence, &reallen,
-                                &l);
-    FORW;
-    if (len < reallen)
-       return ASN1_OVERRUN;
-    len = reallen;
     {
-       size_t origlen = len;
-       int oldret = ret;
-       ret = 0;
-       (data)->len = 0;
-       (data)->val = NULL;
-       while (ret < origlen) {
-           (data)->len++;
-           (data)->val =
-               realloc((data)->val, sizeof(*((data)->val)) * (data)->len);
-           e = decode_HostAddress(p, len, &(data)->val[(data)->len - 1], &l);
-           FORW;
-           len = origlen - ret;
-       }
-       ret += oldret;
+       size_t Top_datalen, Top_oldlen;
+       Der_type Top_type;
+       e = der_match_tag_and_length(p, len, ASN1_C_UNIV, &Top_type, UT_Sequence, &Top_datalen, &l);
+       if (e == 0 && Top_type != CONS) {
+           e = ASN1_BAD_ID;
+       }
+       if (e)
+           goto fail;
+       p += l;
+       len -= l;
+       ret += l;
+       Top_oldlen = len;
+       if (Top_datalen > len) {
+           e = ASN1_OVERRUN;
+           goto fail;
+       }
+       len = Top_datalen;
+       {
+           size_t Top_Tag_origlen = len;
+           size_t Top_Tag_oldret = ret;
+           size_t Top_Tag_olen = 0;
+           void *Top_Tag_tmp;
+           ret = 0;
+           (data)->len = 0;
+           (data)->val = NULL;
+           while (ret < Top_Tag_origlen) {
+               size_t Top_Tag_nlen = Top_Tag_olen + sizeof(*((data)->val));
+               if (Top_Tag_olen > Top_Tag_nlen) {
+                   e = ASN1_OVERFLOW;
+                   goto fail;
+               }
+               Top_Tag_olen = Top_Tag_nlen;
+               Top_Tag_tmp = realloc((data)->val, Top_Tag_olen);
+               if (Top_Tag_tmp == NULL) {
+                   e = ENOMEM;
+                   goto fail;
+               }
+               (data)->val = Top_Tag_tmp;
+               e = decode_HostAddress(p, len, &(data)->val[(data)->len], &l);
+               if (e)
+                   goto fail;
+               p += l;
+               len -= l;
+               ret += l;
+               (data)->len++;
+               len = Top_Tag_origlen - ret;
+           }
+           ret += Top_Tag_oldret;
+       }
+       len = Top_oldlen - Top_datalen;
     }
     if (size)
        *size = ret;
     return 0;
-  fail:
+fail:
     free_HostAddresses(data);
     return e;
 }
@@ -829,6 +1406,7 @@ free_HostAddresses(HostAddresses * data)
        (data)->len--;
     }
     free((data)->val);
+    (data)->val = NULL;
 }
 
 size_t
@@ -836,31 +1414,40 @@ length_HostAddresses(const HostAddresses * data)
 {
     size_t ret = 0;
     {
-       int oldret = ret;
+       int Top_tag_oldret = ret;
        int i;
        ret = 0;
        for (i = (data)->len - 1; i >= 0; --i) {
+           int Top_tag_for_oldret = ret;
+           ret = 0;
            ret += length_HostAddress(&(data)->val[i]);
+           ret += Top_tag_for_oldret;
        }
-       ret += 1 + length_len(ret) + oldret;
+       ret += Top_tag_oldret;
     }
+    ret += 1 + der_length_len(ret);
     return ret;
 }
 
 int
 copy_HostAddresses(const HostAddresses * from, HostAddresses * to)
 {
-    if (((to)->val = malloc((from)->len * sizeof(*(to)->val))) == NULL
-       && (from)->len != 0)
-       return ENOMEM;
+    memset(to, 0, sizeof(*to));
+    if (((to)->val = malloc((from)->len * sizeof(*(to)->val))) == NULL && (from)->len != 0)
+       goto fail;
     for ((to)->len = 0; (to)->len < (from)->len; (to)->len++) {
        if (copy_HostAddress(&(from)->val[(to)->len], &(to)->val[(to)->len]))
-           return ENOMEM;
+           goto fail;
     }
     return 0;
+fail:
+    free_HostAddresses(to);
+    return ENOMEM;
 }
 
-/* Generated from /home/lha/src/cvs/heimdal/lib/asn1/k5.asn1 */
+
+
+/* Generated from ./krb5.asn1 */
 /* Do not edit */
 
 #include <stdio.h>
@@ -868,130 +1455,179 @@ copy_HostAddresses(const HostAddresses * from, HostAddresses * to)
 #include <time.h>
 #include <string.h>
 #include <errno.h>
+#include <limits.h>
 #include <asn1_err.h>
 
-#define BACK if (e) return e; p -= l; len -= l; ret += l
-
 int
-encode_HostAddress(unsigned char *p, size_t len, const HostAddress * data,
-                  size_t * size)
+encode_HostAddress(unsigned char *p, size_t len, const HostAddress * data, size_t * size)
 {
     size_t ret = 0;
     size_t l;
     int i, e;
 
     i = 0;
+/* address */
     {
-       int oldret = ret;
+       size_t Top_tag_oldret = ret;
        ret = 0;
-       e = encode_octet_string(p, len, &(data)->address, &l);
-       BACK;
-       e = der_put_length_and_tag(p, len, ret, Der_CONTEXT, CONS, 1, &l);
-       BACK;
-       ret += oldret;
-    }
+       e = der_put_octet_string(p, len, &(data)->address, &l);
+       if (e)
+           return e;
+       p -= l;
+       len -= l;
+       ret += l;
+
+       e = der_put_length_and_tag(p, len, ret, ASN1_C_UNIV, PRIM, UT_OctetString, &l);
+       if (e)
+           return e;
+       p -= l;
+       len -= l;
+       ret += l;
+
+       e = der_put_length_and_tag(p, len, ret, ASN1_C_CONTEXT, CONS, 1, &l);
+       if (e)
+           return e;
+       p -= l;
+       len -= l;
+       ret += l;
+
+       ret += Top_tag_oldret;
+    }
+/* addr-type */
     {
-       int oldret = ret;
+       size_t Top_tag_oldret = ret;
        ret = 0;
-       e = encode_integer(p, len, &(data)->addr_type, &l);
-       BACK;
-       e = der_put_length_and_tag(p, len, ret, Der_CONTEXT, CONS, 0, &l);
-       BACK;
-       ret += oldret;
-    }
-    e = der_put_length_and_tag(p, len, ret, UNIV, CONS, UT_Sequence, &l);
-    BACK;
+       e = encode_krb5int32(p, len, &(data)->addr_type, &l);
+       if (e)
+           return e;
+       p -= l;
+       len -= l;
+       ret += l;
+
+       e = der_put_length_and_tag(p, len, ret, ASN1_C_CONTEXT, CONS, 0, &l);
+       if (e)
+           return e;
+       p -= l;
+       len -= l;
+       ret += l;
+
+       ret += Top_tag_oldret;
+    }
+    e = der_put_length_and_tag(p, len, ret, ASN1_C_UNIV, CONS, UT_Sequence, &l);
+    if (e)
+       return e;
+    p -= l;
+    len -= l;
+    ret += l;
+
     *size = ret;
     return 0;
 }
 
-#define FORW if(e) goto fail; p += l; len -= l; ret += l
-
 int
-decode_HostAddress(const unsigned char *p, size_t len, HostAddress * data,
-                  size_t * size)
+decode_HostAddress(const unsigned char *p, size_t len, HostAddress * data, size_t * size)
 {
-    size_t ret = 0, reallen;
+    size_t ret = 0;
     size_t l;
     int e;
 
     memset(data, 0, sizeof(*data));
-    reallen = 0;
-    e = der_match_tag_and_length(p, len, UNIV, CONS, UT_Sequence, &reallen,
-                                &l);
-    FORW;
-    {
-       int dce_fix;
-       if ((dce_fix = fix_dce(reallen, &len)) < 0)
-           return ASN1_BAD_FORMAT;
+    {
+       size_t Top_datalen, Top_oldlen;
+       Der_type Top_type;
+       e = der_match_tag_and_length(p, len, ASN1_C_UNIV, &Top_type, UT_Sequence, &Top_datalen, &l);
+       if (e == 0 && Top_type != CONS) {
+           e = ASN1_BAD_ID;
+       }
+       if (e)
+           goto fail;
+       p += l;
+       len -= l;
+       ret += l;
+       Top_oldlen = len;
+       if (Top_datalen > len) {
+           e = ASN1_OVERRUN;
+           goto fail;
+       }
+       len = Top_datalen;
        {
-           size_t newlen, oldlen;
-
-           e = der_match_tag(p, len, Der_CONTEXT, CONS, 0, &l);
+           size_t addr_type_datalen, addr_type_oldlen;
+           Der_type addr_type_type;
+           e = der_match_tag_and_length(p, len, ASN1_C_CONTEXT, &addr_type_type, 0, &addr_type_datalen, &l);
+           if (e == 0 && addr_type_type != CONS) {
+               e = ASN1_BAD_ID;
+           }
            if (e)
-               return e;
-           else {
-               p += l;
-               len -= l;
-               ret += l;
-               e = der_get_length(p, len, &newlen, &l);
-               FORW;
-               {
-                   int dce_fix;
-                   oldlen = len;
-                   if ((dce_fix = fix_dce(newlen, &len)) < 0)
-                       return ASN1_BAD_FORMAT;
-                   e = decode_integer(p, len, &(data)->addr_type, &l);
-                   FORW;
-                   if (dce_fix) {
-                       e = der_match_tag_and_length(p, len, (Der_class) 0,
-                                                    (Der_type) 0, 0,
-                                                    &reallen, &l);
-                       FORW;
-                   } else
-                       len = oldlen - newlen;
-               }
+               goto fail;
+           p += l;
+           len -= l;
+           ret += l;
+           addr_type_oldlen = len;
+           if (addr_type_datalen > len) {
+               e = ASN1_OVERRUN;
+               goto fail;
            }
+           len = addr_type_datalen;
+           e = decode_krb5int32(p, len, &(data)->addr_type, &l);
+           if (e)
+               goto fail;
+           p += l;
+           len -= l;
+           ret += l;
+           len = addr_type_oldlen - addr_type_datalen;
        }
        {
-           size_t newlen, oldlen;
-
-           e = der_match_tag(p, len, Der_CONTEXT, CONS, 1, &l);
+           size_t address_datalen, address_oldlen;
+           Der_type address_type;
+           e = der_match_tag_and_length(p, len, ASN1_C_CONTEXT, &address_type, 1, &address_datalen, &l);
+           if (e == 0 && address_type != CONS) {
+               e = ASN1_BAD_ID;
+           }
            if (e)
-               return e;
-           else {
+               goto fail;
+           p += l;
+           len -= l;
+           ret += l;
+           address_oldlen = len;
+           if (address_datalen > len) {
+               e = ASN1_OVERRUN;
+               goto fail;
+           }
+           len = address_datalen;
+           {
+               size_t address_Tag_datalen, address_Tag_oldlen;
+               Der_type address_Tag_type;
+               e = der_match_tag_and_length(p, len, ASN1_C_UNIV, &address_Tag_type, UT_OctetString, &address_Tag_datalen, &l);
+               if (e == 0 && address_Tag_type != PRIM) {
+                   e = ASN1_BAD_ID;
+               }
+               if (e)
+                   goto fail;
                p += l;
                len -= l;
                ret += l;
-               e = der_get_length(p, len, &newlen, &l);
-               FORW;
-               {
-                   int dce_fix;
-                   oldlen = len;
-                   if ((dce_fix = fix_dce(newlen, &len)) < 0)
-                       return ASN1_BAD_FORMAT;
-                   e = decode_octet_string(p, len, &(data)->address, &l);
-                   FORW;
-                   if (dce_fix) {
-                       e = der_match_tag_and_length(p, len, (Der_class) 0,
-                                                    (Der_type) 0, 0,
-                                                    &reallen, &l);
-                       FORW;
-                   } else
-                       len = oldlen - newlen;
+               address_Tag_oldlen = len;
+               if (address_Tag_datalen > len) {
+                   e = ASN1_OVERRUN;
+                   goto fail;
                }
+               len = address_Tag_datalen;
+               e = der_get_octet_string(p, len, &(data)->address, &l);
+               if (e)
+                   goto fail;
+               p += l;
+               len -= l;
+               ret += l;
+               len = address_Tag_oldlen - address_Tag_datalen;
            }
+           len = address_oldlen - address_datalen;
        }
-       if (dce_fix) {
-           e = der_match_tag_and_length(p, len, (Der_class) 0, (Der_type) 0,
-                                        0, &reallen, &l);
-           FORW;
-       }
+       len = Top_oldlen - Top_datalen;
     }
     if (size)
        *size = ret;
     return 0;
-  fail:
+fail:
     free_HostAddress(data);
     return e;
 }
@@ -999,7 +1635,8 @@ decode_HostAddress(const unsigned char *p, size_t len, HostAddress * data,
 void
 free_HostAddress(HostAddress * data)
 {
-    free_octet_string(&(data)->address);
+    free_krb5int32(&(data)->addr_type);
+    der_free_octet_string(&(data)->address);
 }
 
 size_t
@@ -1007,31 +1644,41 @@ length_HostAddress(const HostAddress * data)
 {
     size_t ret = 0;
     {
-       int oldret = ret;
+       size_t Top_tag_oldret = ret;
        ret = 0;
-       ret += length_integer(&(data)->addr_type);
-       ret += 1 + length_len(ret) + oldret;
+       ret += length_krb5int32(&(data)->addr_type);
+       ret += 1 + der_length_len(ret);
+       ret += Top_tag_oldret;
     }
     {
-       int oldret = ret;
+       size_t Top_tag_oldret = ret;
        ret = 0;
-       ret += length_octet_string(&(data)->address);
-       ret += 1 + length_len(ret) + oldret;
+       ret += der_length_octet_string(&(data)->address);
+       ret += 1 + der_length_len(ret);
+       ret += 1 + der_length_len(ret);
+       ret += Top_tag_oldret;
     }
-    ret += 1 + length_len(ret);
+    ret += 1 + der_length_len(ret);
     return ret;
 }
 
 int
 copy_HostAddress(const HostAddress * from, HostAddress * to)
 {
-    *(&(to)->addr_type) = *(&(from)->addr_type);
-    if (copy_octet_string(&(from)->address, &(to)->address))
-       return ENOMEM;
+    memset(to, 0, sizeof(*to));
+    if (copy_krb5int32(&(from)->addr_type, &(to)->addr_type))
+       goto fail;
+    if (der_copy_octet_string(&(from)->address, &(to)->address))
+       goto fail;
     return 0;
+fail:
+    free_HostAddress(to);
+    return ENOMEM;
 }
 
-/* Generated from /home/lha/src/cvs/heimdal/lib/asn1/k5.asn1 */
+
+
+/* Generated from ./krb5.asn1 */
 /* Do not edit */
 
 #include <stdio.h>
@@ -1039,13 +1686,11 @@ copy_HostAddress(const HostAddress * from, HostAddress * to)
 #include <time.h>
 #include <string.h>
 #include <errno.h>
+#include <limits.h>
 #include <asn1_err.h>
 
-#define BACK if (e) return e; p -= l; len -= l; ret += l
-
 int
-encode_AuthorizationData(unsigned char *p, size_t len,
-                        const AuthorizationData * data, size_t * size)
+encode_AuthorizationData(unsigned char *p, size_t len, const AuthorizationData * data, size_t * size)
 {
     size_t ret = 0;
     size_t l;
@@ -1053,152 +1698,92 @@ encode_AuthorizationData(unsigned char *p, size_t len,
 
     i = 0;
     for (i = (data)->len - 1; i >= 0; --i) {
-       int oldret = ret;
+       size_t Top_tag_for_oldret = ret;
        ret = 0;
-       {
-           int oldret = ret;
-           ret = 0;
-           e = encode_octet_string(p, len, &(&(data)->val[i])->ad_data, &l);
-           BACK;
-           e = der_put_length_and_tag(p, len, ret, Der_CONTEXT, CONS, 1, &l);
-           BACK;
-           ret += oldret;
-       }
-       {
-           int oldret = ret;
-           ret = 0;
-           e = encode_integer(p, len, &(&(data)->val[i])->ad_type, &l);
-           BACK;
-           e = der_put_length_and_tag(p, len, ret, Der_CONTEXT, CONS, 0, &l);
-           BACK;
-           ret += oldret;
-       }
-       e = der_put_length_and_tag(p, len, ret, UNIV, CONS, UT_Sequence, &l);
-       BACK;
-       ret += oldret;
-    }
-    e = der_put_length_and_tag(p, len, ret, UNIV, CONS, UT_Sequence, &l);
-    BACK;
+       e = encode_AuthorizationDataElement(p, len, &(data)->val[i], &l);
+       if (e)
+           return e;
+       p -= l;
+       len -= l;
+       ret += l;
+
+       ret += Top_tag_for_oldret;
+    }
+    e = der_put_length_and_tag(p, len, ret, ASN1_C_UNIV, CONS, UT_Sequence, &l);
+    if (e)
+       return e;
+    p -= l;
+    len -= l;
+    ret += l;
+
     *size = ret;
     return 0;
 }
 
-#define FORW if(e) goto fail; p += l; len -= l; ret += l
-
 int
-decode_AuthorizationData(const unsigned char *p, size_t len,
-                        AuthorizationData * data, size_t * size)
+decode_AuthorizationData(const unsigned char *p, size_t len, AuthorizationData * data, size_t * size)
 {
-    size_t ret = 0, reallen;
+    size_t ret = 0;
     size_t l;
     int e;
 
     memset(data, 0, sizeof(*data));
-    reallen = 0;
-    e = der_match_tag_and_length(p, len, UNIV, CONS, UT_Sequence, &reallen,
-                                &l);
-    FORW;
-    if (len < reallen)
-       return ASN1_OVERRUN;
-    len = reallen;
     {
-       size_t origlen = len;
-       int oldret = ret;
-       ret = 0;
-       (data)->len = 0;
-       (data)->val = NULL;
-       while (ret < origlen) {
-           (data)->len++;
-           (data)->val =
-               realloc((data)->val, sizeof(*((data)->val)) * (data)->len);
-           e = der_match_tag_and_length(p, len, UNIV, CONS, UT_Sequence,
-                                        &reallen, &l);
-           FORW;
-           {
-               int dce_fix;
-               if ((dce_fix = fix_dce(reallen, &len)) < 0)
-                   return ASN1_BAD_FORMAT;
-               {
-                   size_t newlen, oldlen;
-
-                   e = der_match_tag(p, len, Der_CONTEXT, CONS, 0, &l);
-                   if (e)
-                       return e;
-                   else {
-                       p += l;
-                       len -= l;
-                       ret += l;
-                       e = der_get_length(p, len, &newlen, &l);
-                       FORW;
-                       {
-                           int dce_fix;
-                           oldlen = len;
-                           if ((dce_fix = fix_dce(newlen, &len)) < 0)
-                               return ASN1_BAD_FORMAT;
-                           e = decode_integer(p, len,
-                                              &(&(data)->
-                                                val[(data)->len -
-                                                    1])->ad_type, &l);
-                           FORW;
-                           if (dce_fix) {
-                               e = der_match_tag_and_length(p, len,
-                                                            (Der_class) 0,
-                                                            (Der_type) 0, 0,
-                                                            &reallen, &l);
-                               FORW;
-                           } else
-                               len = oldlen - newlen;
-                       }
-                   }
-               }
-               {
-                   size_t newlen, oldlen;
-
-                   e = der_match_tag(p, len, Der_CONTEXT, CONS, 1, &l);
-                   if (e)
-                       return e;
-                   else {
-                       p += l;
-                       len -= l;
-                       ret += l;
-                       e = der_get_length(p, len, &newlen, &l);
-                       FORW;
-                       {
-                           int dce_fix;
-                           oldlen = len;
-                           if ((dce_fix = fix_dce(newlen, &len)) < 0)
-                               return ASN1_BAD_FORMAT;
-                           e = decode_octet_string(p, len,
-                                                   &(&(data)->
-                                                     val[(data)->len -
-                                                         1])->ad_data, &l);
-                           FORW;
-                           if (dce_fix) {
-                               e = der_match_tag_and_length(p, len,
-                                                            (Der_class) 0,
-                                                            (Der_type) 0, 0,
-                                                            &reallen, &l);
-                               FORW;
-                           } else
-                               len = oldlen - newlen;
-                       }
-                   }
+       size_t Top_datalen, Top_oldlen;
+       Der_type Top_type;
+       e = der_match_tag_and_length(p, len, ASN1_C_UNIV, &Top_type, UT_Sequence, &Top_datalen, &l);
+       if (e == 0 && Top_type != CONS) {
+           e = ASN1_BAD_ID;
+       }
+       if (e)
+           goto fail;
+       p += l;
+       len -= l;
+       ret += l;
+       Top_oldlen = len;
+       if (Top_datalen > len) {
+           e = ASN1_OVERRUN;
+           goto fail;
+       }
+       len = Top_datalen;
+       {
+           size_t Top_Tag_origlen = len;
+           size_t Top_Tag_oldret = ret;
+           size_t Top_Tag_olen = 0;
+           void *Top_Tag_tmp;
+           ret = 0;
+           (data)->len = 0;
+           (data)->val = NULL;
+           while (ret < Top_Tag_origlen) {
+               size_t Top_Tag_nlen = Top_Tag_olen + sizeof(*((data)->val));
+               if (Top_Tag_olen > Top_Tag_nlen) {
+                   e = ASN1_OVERFLOW;
+                   goto fail;
                }
-               if (dce_fix) {
-                   e = der_match_tag_and_length(p, len, (Der_class) 0,
-                                                (Der_type) 0, 0, &reallen,
-                                                &l);
-                   FORW;
+               Top_Tag_olen = Top_Tag_nlen;
+               Top_Tag_tmp = realloc((data)->val, Top_Tag_olen);
+               if (Top_Tag_tmp == NULL) {
+                   e = ENOMEM;
+                   goto fail;
                }
+               (data)->val = Top_Tag_tmp;
+               e = decode_AuthorizationDataElement(p, len, &(data)->val[(data)->len], &l);
+               if (e)
+                   goto fail;
+               p += l;
+               len -= l;
+               ret += l;
+               (data)->len++;
+               len = Top_Tag_origlen - ret;
            }
-           len = origlen - ret;
+           ret += Top_Tag_oldret;
        }
-       ret += oldret;
+       len = Top_oldlen - Top_datalen;
     }
     if (size)
        *size = ret;
     return 0;
-  fail:
+fail:
     free_AuthorizationData(data);
     return e;
 }
@@ -1207,10 +1792,11 @@ void
 free_AuthorizationData(AuthorizationData * data)
 {
     while ((data)->len) {
-       free_octet_string(&(&(data)->val[(data)->len - 1])->ad_data);
+       free_AuthorizationDataElement(&(data)->val[(data)->len - 1]);
        (data)->len--;
     }
     free((data)->val);
+    (data)->val = NULL;
 }
 
 size_t
@@ -1218,47 +1804,77 @@ length_AuthorizationData(const AuthorizationData * data)
 {
     size_t ret = 0;
     {
-       int oldret = ret;
+       int Top_tag_oldret = ret;
        int i;
        ret = 0;
        for (i = (data)->len - 1; i >= 0; --i) {
-           {
-               int oldret = ret;
-               ret = 0;
-               ret += length_integer(&(&(data)->val[i])->ad_type);
-               ret += 1 + length_len(ret) + oldret;
-           }
-           {
-               int oldret = ret;
-               ret = 0;
-               ret += length_octet_string(&(&(data)->val[i])->ad_data);
-               ret += 1 + length_len(ret) + oldret;
-           }
-           ret += 1 + length_len(ret);
+           int Top_tag_for_oldret = ret;
+           ret = 0;
+           ret += length_AuthorizationDataElement(&(data)->val[i]);
+           ret += Top_tag_for_oldret;
        }
-       ret += 1 + length_len(ret) + oldret;
+       ret += Top_tag_oldret;
     }
+    ret += 1 + der_length_len(ret);
     return ret;
 }
 
 int
 copy_AuthorizationData(const AuthorizationData * from, AuthorizationData * to)
 {
-    if (((to)->val = malloc((from)->len * sizeof(*(to)->val))) == NULL
-       && (from)->len != 0)
-       return ENOMEM;
+    memset(to, 0, sizeof(*to));
+    if (((to)->val = malloc((from)->len * sizeof(*(to)->val))) == NULL && (from)->len != 0)
+       goto fail;
     for ((to)->len = 0; (to)->len < (from)->len; (to)->len++) {
-       *(&(&(to)->val[(to)->len])->ad_type) =
-           *(&(&(from)->val[(to)->len])->ad_type);
-       if (copy_octet_string
-           (&(&(from)->val[(to)->len])->ad_data,
-            &(&(to)->val[(to)->len])->ad_data))
-           return ENOMEM;
+       if (copy_AuthorizationDataElement(&(from)->val[(to)->len], &(to)->val[(to)->len]))
+           goto fail;
     }
     return 0;
+fail:
+    free_AuthorizationData(to);
+    return ENOMEM;
+}
+
+int
+add_AuthorizationData(AuthorizationData * data, const AuthorizationDataElement * element)
+{
+    int ret;
+    void *ptr;
+
+    ptr = realloc(data->val,
+                 (data->len + 1) * sizeof(data->val[0]));
+    if (ptr == NULL)
+       return ENOMEM;
+    data->val = ptr;
+
+    ret = copy_AuthorizationDataElement(element, &data->val[data->len]);
+    if (ret)
+       return ret;
+    data->len++;
+    return 0;
 }
 
-/* Generated from /home/lha/src/cvs/heimdal/lib/asn1/k5.asn1 */
+int
+remove_AuthorizationData(AuthorizationData * data, unsigned int element)
+{
+    void *ptr;
+
+    if (data->len == 0 || element >= data->len)
+       return ASN1_OVERRUN;
+    free_AuthorizationDataElement(&data->val[element]);
+    data->len--;
+    if (element < data->len)
+       memmove(&data->val[element], &data->val[element + 1],
+               sizeof(data->val[0]) * data->len);
+    ptr = realloc(data->val, data->len * sizeof(data->val[0]));
+    if (ptr != NULL || data->len == 0)
+       data->val = ptr;
+    return 0;
+}
+
+
+
+/* Generated from ./krb5.asn1 */
 /* Do not edit */
 
 #include <stdio.h>
@@ -1266,518 +1882,621 @@ copy_AuthorizationData(const AuthorizationData * from, AuthorizationData * to)
 #include <time.h>
 #include <string.h>
 #include <errno.h>
+#include <limits.h>
 #include <asn1_err.h>
 
-#define BACK if (e) return e; p -= l; len -= l; ret += l
-
 int
-encode_EncTicketPart(unsigned char *p, size_t len, const EncTicketPart * data,
-                    size_t * size)
+encode_EncTicketPart(unsigned char *p, size_t len, const EncTicketPart * data, size_t * size)
 {
     size_t ret = 0;
     size_t l;
     int i, e;
 
     i = 0;
+/* authorization-data */
     if ((data)->authorization_data) {
-       int oldret = ret;
+       size_t Top_tag_tag_oldret = ret;
        ret = 0;
        e = encode_AuthorizationData(p, len, (data)->authorization_data, &l);
-       BACK;
-       e = der_put_length_and_tag(p, len, ret, Der_CONTEXT, CONS, 10, &l);
-       BACK;
-       ret += oldret;
-    }
+       if (e)
+           return e;
+       p -= l;
+       len -= l;
+       ret += l;
+
+       e = der_put_length_and_tag(p, len, ret, ASN1_C_CONTEXT, CONS, 10, &l);
+       if (e)
+           return e;
+       p -= l;
+       len -= l;
+       ret += l;
+
+       ret += Top_tag_tag_oldret;
+    }
+/* caddr */
     if ((data)->caddr) {
-       int oldret = ret;
+       size_t Top_tag_tag_oldret = ret;
        ret = 0;
        e = encode_HostAddresses(p, len, (data)->caddr, &l);
-       BACK;
-       e = der_put_length_and_tag(p, len, ret, Der_CONTEXT, CONS, 9, &l);
-       BACK;
-       ret += oldret;
-    }
+       if (e)
+           return e;
+       p -= l;
+       len -= l;
+       ret += l;
+
+       e = der_put_length_and_tag(p, len, ret, ASN1_C_CONTEXT, CONS, 9, &l);
+       if (e)
+           return e;
+       p -= l;
+       len -= l;
+       ret += l;
+
+       ret += Top_tag_tag_oldret;
+    }
+/* renew-till */
     if ((data)->renew_till) {
-       int oldret = ret;
+       size_t Top_tag_tag_oldret = ret;
        ret = 0;
        e = encode_KerberosTime(p, len, (data)->renew_till, &l);
-       BACK;
-       e = der_put_length_and_tag(p, len, ret, Der_CONTEXT, CONS, 8, &l);
-       BACK;
-       ret += oldret;
-    }
+       if (e)
+           return e;
+       p -= l;
+       len -= l;
+       ret += l;
+
+       e = der_put_length_and_tag(p, len, ret, ASN1_C_CONTEXT, CONS, 8, &l);
+       if (e)
+           return e;
+       p -= l;
+       len -= l;
+       ret += l;
+
+       ret += Top_tag_tag_oldret;
+    }
+/* endtime */
     {
-       int oldret = ret;
+       size_t Top_tag_tag_oldret = ret;
        ret = 0;
        e = encode_KerberosTime(p, len, &(data)->endtime, &l);
-       BACK;
-       e = der_put_length_and_tag(p, len, ret, Der_CONTEXT, CONS, 7, &l);
-       BACK;
-       ret += oldret;
-    }
+       if (e)
+           return e;
+       p -= l;
+       len -= l;
+       ret += l;
+
+       e = der_put_length_and_tag(p, len, ret, ASN1_C_CONTEXT, CONS, 7, &l);
+       if (e)
+           return e;
+       p -= l;
+       len -= l;
+       ret += l;
+
+       ret += Top_tag_tag_oldret;
+    }
+/* starttime */
     if ((data)->starttime) {
-       int oldret = ret;
+       size_t Top_tag_tag_oldret = ret;
        ret = 0;
        e = encode_KerberosTime(p, len, (data)->starttime, &l);
-       BACK;
-       e = der_put_length_and_tag(p, len, ret, Der_CONTEXT, CONS, 6, &l);
-       BACK;
-       ret += oldret;
-    }
+       if (e)
+           return e;
+       p -= l;
+       len -= l;
+       ret += l;
+
+       e = der_put_length_and_tag(p, len, ret, ASN1_C_CONTEXT, CONS, 6, &l);
+       if (e)
+           return e;
+       p -= l;
+       len -= l;
+       ret += l;
+
+       ret += Top_tag_tag_oldret;
+    }
+/* authtime */
     {
-       int oldret = ret;
+       size_t Top_tag_tag_oldret = ret;
        ret = 0;
        e = encode_KerberosTime(p, len, &(data)->authtime, &l);
-       BACK;
-       e = der_put_length_and_tag(p, len, ret, Der_CONTEXT, CONS, 5, &l);
-       BACK;
-       ret += oldret;
-    }
+       if (e)
+           return e;
+       p -= l;
+       len -= l;
+       ret += l;
+
+       e = der_put_length_and_tag(p, len, ret, ASN1_C_CONTEXT, CONS, 5, &l);
+       if (e)
+           return e;
+       p -= l;
+       len -= l;
+       ret += l;
+
+       ret += Top_tag_tag_oldret;
+    }
+/* transited */
     {
-       int oldret = ret;
+       size_t Top_tag_tag_oldret = ret;
        ret = 0;
        e = encode_TransitedEncoding(p, len, &(data)->transited, &l);
-       BACK;
-       e = der_put_length_and_tag(p, len, ret, Der_CONTEXT, CONS, 4, &l);
-       BACK;
-       ret += oldret;
-    }
+       if (e)
+           return e;
+       p -= l;
+       len -= l;
+       ret += l;
+
+       e = der_put_length_and_tag(p, len, ret, ASN1_C_CONTEXT, CONS, 4, &l);
+       if (e)
+           return e;
+       p -= l;
+       len -= l;
+       ret += l;
+
+       ret += Top_tag_tag_oldret;
+    }
+/* cname */
     {
-       int oldret = ret;
+       size_t Top_tag_tag_oldret = ret;
        ret = 0;
        e = encode_PrincipalName(p, len, &(data)->cname, &l);
-       BACK;
-       e = der_put_length_and_tag(p, len, ret, Der_CONTEXT, CONS, 3, &l);
-       BACK;
-       ret += oldret;
-    }
+       if (e)
+           return e;
+       p -= l;
+       len -= l;
+       ret += l;
+
+       e = der_put_length_and_tag(p, len, ret, ASN1_C_CONTEXT, CONS, 3, &l);
+       if (e)
+           return e;
+       p -= l;
+       len -= l;
+       ret += l;
+
+       ret += Top_tag_tag_oldret;
+    }
+/* crealm */
     {
-       int oldret = ret;
+       size_t Top_tag_tag_oldret = ret;
        ret = 0;
        e = encode_Realm(p, len, &(data)->crealm, &l);
-       BACK;
-       e = der_put_length_and_tag(p, len, ret, Der_CONTEXT, CONS, 2, &l);
-       BACK;
-       ret += oldret;
-    }
+       if (e)
+           return e;
+       p -= l;
+       len -= l;
+       ret += l;
+
+       e = der_put_length_and_tag(p, len, ret, ASN1_C_CONTEXT, CONS, 2, &l);
+       if (e)
+           return e;
+       p -= l;
+       len -= l;
+       ret += l;
+
+       ret += Top_tag_tag_oldret;
+    }
+/* key */
     {
-       int oldret = ret;
+       size_t Top_tag_tag_oldret = ret;
        ret = 0;
        e = encode_EncryptionKey(p, len, &(data)->key, &l);
-       BACK;
-       e = der_put_length_and_tag(p, len, ret, Der_CONTEXT, CONS, 1, &l);
-       BACK;
-       ret += oldret;
-    }
+       if (e)
+           return e;
+       p -= l;
+       len -= l;
+       ret += l;
+
+       e = der_put_length_and_tag(p, len, ret, ASN1_C_CONTEXT, CONS, 1, &l);
+       if (e)
+           return e;
+       p -= l;
+       len -= l;
+       ret += l;
+
+       ret += Top_tag_tag_oldret;
+    }
+/* flags */
     {
-       int oldret = ret;
+       size_t Top_tag_tag_oldret = ret;
        ret = 0;
        e = encode_TicketFlags(p, len, &(data)->flags, &l);
-       BACK;
-       e = der_put_length_and_tag(p, len, ret, Der_CONTEXT, CONS, 0, &l);
-       BACK;
-       ret += oldret;
-    }
-    e = der_put_length_and_tag(p, len, ret, UNIV, CONS, UT_Sequence, &l);
-    BACK;
-    e = der_put_length_and_tag(p, len, ret, APPL, CONS, 3, &l);
-    BACK;
+       if (e)
+           return e;
+       p -= l;
+       len -= l;
+       ret += l;
+
+       e = der_put_length_and_tag(p, len, ret, ASN1_C_CONTEXT, CONS, 0, &l);
+       if (e)
+           return e;
+       p -= l;
+       len -= l;
+       ret += l;
+
+       ret += Top_tag_tag_oldret;
+    }
+    e = der_put_length_and_tag(p, len, ret, ASN1_C_UNIV, CONS, UT_Sequence, &l);
+    if (e)
+       return e;
+    p -= l;
+    len -= l;
+    ret += l;
+
+    e = der_put_length_and_tag(p, len, ret, ASN1_C_APPL, CONS, 3, &l);
+    if (e)
+       return e;
+    p -= l;
+    len -= l;
+    ret += l;
+
     *size = ret;
     return 0;
 }
 
-#define FORW if(e) goto fail; p += l; len -= l; ret += l
-
 int
-decode_EncTicketPart(const unsigned char *p, size_t len, EncTicketPart * data,
-                    size_t * size)
+decode_EncTicketPart(const unsigned char *p, size_t len, EncTicketPart * data, size_t * size)
 {
-    size_t ret = 0, reallen;
+    size_t ret = 0;
     size_t l;
     int e;
 
     memset(data, 0, sizeof(*data));
-    reallen = 0;
-    e = der_match_tag_and_length(p, len, APPL, CONS, 3, &reallen, &l);
-    FORW;
-    {
-       int dce_fix;
-       if ((dce_fix = fix_dce(reallen, &len)) < 0)
-           return ASN1_BAD_FORMAT;
-       e = der_match_tag_and_length(p, len, UNIV, CONS, UT_Sequence,
-                                    &reallen, &l);
-       FORW;
+    {
+       size_t Top_datalen, Top_oldlen;
+       Der_type Top_type;
+       e = der_match_tag_and_length(p, len, ASN1_C_APPL, &Top_type, 3, &Top_datalen, &l);
+       if (e == 0 && Top_type != CONS) {
+           e = ASN1_BAD_ID;
+       }
+       if (e)
+           goto fail;
+       p += l;
+       len -= l;
+       ret += l;
+       Top_oldlen = len;
+       if (Top_datalen > len) {
+           e = ASN1_OVERRUN;
+           goto fail;
+       }
+       len = Top_datalen;
        {
-           int dce_fix;
-           if ((dce_fix = fix_dce(reallen, &len)) < 0)
-               return ASN1_BAD_FORMAT;
+           size_t Top_Tag_datalen, Top_Tag_oldlen;
+           Der_type Top_Tag_type;
+           e = der_match_tag_and_length(p, len, ASN1_C_UNIV, &Top_Tag_type, UT_Sequence, &Top_Tag_datalen, &l);
+           if (e == 0 && Top_Tag_type != CONS) {
+               e = ASN1_BAD_ID;
+           }
+           if (e)
+               goto fail;
+           p += l;
+           len -= l;
+           ret += l;
+           Top_Tag_oldlen = len;
+           if (Top_Tag_datalen > len) {
+               e = ASN1_OVERRUN;
+               goto fail;
+           }
+           len = Top_Tag_datalen;
            {
-               size_t newlen, oldlen;
-
-               e = der_match_tag(p, len, Der_CONTEXT, CONS, 0, &l);
+               size_t flags_datalen, flags_oldlen;
+               Der_type flags_type;
+               e = der_match_tag_and_length(p, len, ASN1_C_CONTEXT, &flags_type, 0, &flags_datalen, &l);
+               if (e == 0 && flags_type != CONS) {
+                   e = ASN1_BAD_ID;
+               }
                if (e)
-                   return e;
-               else {
-                   p += l;
-                   len -= l;
-                   ret += l;
-                   e = der_get_length(p, len, &newlen, &l);
-                   FORW;
-                   {
-                       int dce_fix;
-                       oldlen = len;
-                       if ((dce_fix = fix_dce(newlen, &len)) < 0)
-                           return ASN1_BAD_FORMAT;
-                       e = decode_TicketFlags(p, len, &(data)->flags, &l);
-                       FORW;
-                       if (dce_fix) {
-                           e = der_match_tag_and_length(p, len,
-                                                        (Der_class) 0,
-                                                        (Der_type) 0, 0,
-                                                        &reallen, &l);
-                           FORW;
-                       } else
-                           len = oldlen - newlen;
-                   }
+                   goto fail;
+               p += l;
+               len -= l;
+               ret += l;
+               flags_oldlen = len;
+               if (flags_datalen > len) {
+                   e = ASN1_OVERRUN;
+                   goto fail;
                }
+               len = flags_datalen;
+               e = decode_TicketFlags(p, len, &(data)->flags, &l);
+               if (e)
+                   goto fail;
+               p += l;
+               len -= l;
+               ret += l;
+               len = flags_oldlen - flags_datalen;
            }
            {
-               size_t newlen, oldlen;
-
-               e = der_match_tag(p, len, Der_CONTEXT, CONS, 1, &l);
+               size_t key_datalen, key_oldlen;
+               Der_type key_type;
+               e = der_match_tag_and_length(p, len, ASN1_C_CONTEXT, &key_type, 1, &key_datalen, &l);
+               if (e == 0 && key_type != CONS) {
+                   e = ASN1_BAD_ID;
+               }
                if (e)
-                   return e;
-               else {
-                   p += l;
-                   len -= l;
-                   ret += l;
-                   e = der_get_length(p, len, &newlen, &l);
-                   FORW;
-                   {
-                       int dce_fix;
-                       oldlen = len;
-                       if ((dce_fix = fix_dce(newlen, &len)) < 0)
-                           return ASN1_BAD_FORMAT;
-                       e = decode_EncryptionKey(p, len, &(data)->key, &l);
-                       FORW;
-                       if (dce_fix) {
-                           e = der_match_tag_and_length(p, len,
-                                                        (Der_class) 0,
-                                                        (Der_type) 0, 0,
-                                                        &reallen, &l);
-                           FORW;
-                       } else
-                           len = oldlen - newlen;
-                   }
+                   goto fail;
+               p += l;
+               len -= l;
+               ret += l;
+               key_oldlen = len;
+               if (key_datalen > len) {
+                   e = ASN1_OVERRUN;
+                   goto fail;
                }
+               len = key_datalen;
+               e = decode_EncryptionKey(p, len, &(data)->key, &l);
+               if (e)
+                   goto fail;
+               p += l;
+               len -= l;
+               ret += l;
+               len = key_oldlen - key_datalen;
            }
            {
-               size_t newlen, oldlen;
-
-               e = der_match_tag(p, len, Der_CONTEXT, CONS, 2, &l);
+               size_t crealm_datalen, crealm_oldlen;
+               Der_type crealm_type;
+               e = der_match_tag_and_length(p, len, ASN1_C_CONTEXT, &crealm_type, 2, &crealm_datalen, &l);
+               if (e == 0 && crealm_type != CONS) {
+                   e = ASN1_BAD_ID;
+               }
                if (e)
-                   return e;
-               else {
-                   p += l;
-                   len -= l;
-                   ret += l;
-                   e = der_get_length(p, len, &newlen, &l);
-                   FORW;
-                   {
-                       int dce_fix;
-                       oldlen = len;
-                       if ((dce_fix = fix_dce(newlen, &len)) < 0)
-                           return ASN1_BAD_FORMAT;
-                       e = decode_Realm(p, len, &(data)->crealm, &l);
-                       FORW;
-                       if (dce_fix) {
-                           e = der_match_tag_and_length(p, len,
-                                                        (Der_class) 0,
-                                                        (Der_type) 0, 0,
-                                                        &reallen, &l);
-                           FORW;
-                       } else
-                           len = oldlen - newlen;
-                   }
+                   goto fail;
+               p += l;
+               len -= l;
+               ret += l;
+               crealm_oldlen = len;
+               if (crealm_datalen > len) {
+                   e = ASN1_OVERRUN;
+                   goto fail;
                }
+               len = crealm_datalen;
+               e = decode_Realm(p, len, &(data)->crealm, &l);
+               if (e)
+                   goto fail;
+               p += l;
+               len -= l;
+               ret += l;
+               len = crealm_oldlen - crealm_datalen;
            }
            {
-               size_t newlen, oldlen;
-
-               e = der_match_tag(p, len, Der_CONTEXT, CONS, 3, &l);
+               size_t cname_datalen, cname_oldlen;
+               Der_type cname_type;
+               e = der_match_tag_and_length(p, len, ASN1_C_CONTEXT, &cname_type, 3, &cname_datalen, &l);
+               if (e == 0 && cname_type != CONS) {
+                   e = ASN1_BAD_ID;
+               }
                if (e)
-                   return e;
-               else {
-                   p += l;
-                   len -= l;
-                   ret += l;
-                   e = der_get_length(p, len, &newlen, &l);
-                   FORW;
-                   {
-                       int dce_fix;
-                       oldlen = len;
-                       if ((dce_fix = fix_dce(newlen, &len)) < 0)
-                           return ASN1_BAD_FORMAT;
-                       e = decode_PrincipalName(p, len, &(data)->cname, &l);
-                       FORW;
-                       if (dce_fix) {
-                           e = der_match_tag_and_length(p, len,
-                                                        (Der_class) 0,
-                                                        (Der_type) 0, 0,
-                                                        &reallen, &l);
-                           FORW;
-                       } else
-                           len = oldlen - newlen;
-                   }
+                   goto fail;
+               p += l;
+               len -= l;
+               ret += l;
+               cname_oldlen = len;
+               if (cname_datalen > len) {
+                   e = ASN1_OVERRUN;
+                   goto fail;
                }
+               len = cname_datalen;
+               e = decode_PrincipalName(p, len, &(data)->cname, &l);
+               if (e)
+                   goto fail;
+               p += l;
+               len -= l;
+               ret += l;
+               len = cname_oldlen - cname_datalen;
            }
            {
-               size_t newlen, oldlen;
-
-               e = der_match_tag(p, len, Der_CONTEXT, CONS, 4, &l);
+               size_t transited_datalen, transited_oldlen;
+               Der_type transited_type;
+               e = der_match_tag_and_length(p, len, ASN1_C_CONTEXT, &transited_type, 4, &transited_datalen, &l);
+               if (e == 0 && transited_type != CONS) {
+                   e = ASN1_BAD_ID;
+               }
                if (e)
-                   return e;
-               else {
-                   p += l;
-                   len -= l;
-                   ret += l;
-                   e = der_get_length(p, len, &newlen, &l);
-                   FORW;
-                   {
-                       int dce_fix;
-                       oldlen = len;
-                       if ((dce_fix = fix_dce(newlen, &len)) < 0)
-                           return ASN1_BAD_FORMAT;
-                       e = decode_TransitedEncoding(p, len,
-                                                    &(data)->transited, &l);
-                       FORW;
-                       if (dce_fix) {
-                           e = der_match_tag_and_length(p, len,
-                                                        (Der_class) 0,
-                                                        (Der_type) 0, 0,
-                                                        &reallen, &l);
-                           FORW;
-                       } else
-                           len = oldlen - newlen;
-                   }
+                   goto fail;
+               p += l;
+               len -= l;
+               ret += l;
+               transited_oldlen = len;
+               if (transited_datalen > len) {
+                   e = ASN1_OVERRUN;
+                   goto fail;
                }
+               len = transited_datalen;
+               e = decode_TransitedEncoding(p, len, &(data)->transited, &l);
+               if (e)
+                   goto fail;
+               p += l;
+               len -= l;
+               ret += l;
+               len = transited_oldlen - transited_datalen;
            }
            {
-               size_t newlen, oldlen;
-
-               e = der_match_tag(p, len, Der_CONTEXT, CONS, 5, &l);
+               size_t authtime_datalen, authtime_oldlen;
+               Der_type authtime_type;
+               e = der_match_tag_and_length(p, len, ASN1_C_CONTEXT, &authtime_type, 5, &authtime_datalen, &l);
+               if (e == 0 && authtime_type != CONS) {
+                   e = ASN1_BAD_ID;
+               }
                if (e)
-                   return e;
-               else {
-                   p += l;
-                   len -= l;
-                   ret += l;
-                   e = der_get_length(p, len, &newlen, &l);
-                   FORW;
-                   {
-                       int dce_fix;
-                       oldlen = len;
-                       if ((dce_fix = fix_dce(newlen, &len)) < 0)
-                           return ASN1_BAD_FORMAT;
-                       e = decode_KerberosTime(p, len, &(data)->authtime,
-                                               &l);
-                       FORW;
-                       if (dce_fix) {
-                           e = der_match_tag_and_length(p, len,
-                                                        (Der_class) 0,
-                                                        (Der_type) 0, 0,
-                                                        &reallen, &l);
-                           FORW;
-                       } else
-                           len = oldlen - newlen;
-                   }
+                   goto fail;
+               p += l;
+               len -= l;
+               ret += l;
+               authtime_oldlen = len;
+               if (authtime_datalen > len) {
+                   e = ASN1_OVERRUN;
+                   goto fail;
                }
+               len = authtime_datalen;
+               e = decode_KerberosTime(p, len, &(data)->authtime, &l);
+               if (e)
+                   goto fail;
+               p += l;
+               len -= l;
+               ret += l;
+               len = authtime_oldlen - authtime_datalen;
            }
            {
-               size_t newlen, oldlen;
-
-               e = der_match_tag(p, len, Der_CONTEXT, CONS, 6, &l);
-               if (e)
+               size_t starttime_datalen, starttime_oldlen;
+               Der_type starttime_type;
+               e = der_match_tag_and_length(p, len, ASN1_C_CONTEXT, &starttime_type, 6, &starttime_datalen, &l);
+               if (e == 0 && starttime_type != CONS) {
+                   e = ASN1_BAD_ID;
+               }
+               if (e) {
                    (data)->starttime = NULL;
-               else {
+               } else {
+                   (data)->starttime = calloc(1, sizeof(*(data)->starttime));
+                   if ((data)->starttime == NULL) {
+                       e = ENOMEM;
+                       goto fail;
+                   }
                    p += l;
                    len -= l;
                    ret += l;
-                   e = der_get_length(p, len, &newlen, &l);
-                   FORW;
-                   {
-                       int dce_fix;
-                       oldlen = len;
-                       if ((dce_fix = fix_dce(newlen, &len)) < 0)
-                           return ASN1_BAD_FORMAT;
-                       (data)->starttime =
-                           malloc(sizeof(*(data)->starttime));
-                       if ((data)->starttime == NULL)
-                           return ENOMEM;
-                       e = decode_KerberosTime(p, len, (data)->starttime,
-                                               &l);
-                       FORW;
-                       if (dce_fix) {
-                           e = der_match_tag_and_length(p, len,
-                                                        (Der_class) 0,
-                                                        (Der_type) 0, 0,
-                                                        &reallen, &l);
-                           FORW;
-                       } else
-                           len = oldlen - newlen;
+                   starttime_oldlen = len;
+                   if (starttime_datalen > len) {
+                       e = ASN1_OVERRUN;
+                       goto fail;
                    }
-               }
-           }
-           {
-               size_t newlen, oldlen;
-
-               e = der_match_tag(p, len, Der_CONTEXT, CONS, 7, &l);
-               if (e)
-                   return e;
-               else {
+                   len = starttime_datalen;
+                   e = decode_KerberosTime(p, len, (data)->starttime, &l);
+                   if (e)
+                       goto fail;
                    p += l;
                    len -= l;
                    ret += l;
-                   e = der_get_length(p, len, &newlen, &l);
-                   FORW;
-                   {
-                       int dce_fix;
-                       oldlen = len;
-                       if ((dce_fix = fix_dce(newlen, &len)) < 0)
-                           return ASN1_BAD_FORMAT;
-                       e = decode_KerberosTime(p, len, &(data)->endtime, &l);
-                       FORW;
-                       if (dce_fix) {
-                           e = der_match_tag_and_length(p, len,
-                                                        (Der_class) 0,
-                                                        (Der_type) 0, 0,
-                                                        &reallen, &l);
-                           FORW;
-                       } else
-                           len = oldlen - newlen;
-                   }
+                   len = starttime_oldlen - starttime_datalen;
                }
            }
            {
-               size_t newlen, oldlen;
-
-               e = der_match_tag(p, len, Der_CONTEXT, CONS, 8, &l);
+               size_t endtime_datalen, endtime_oldlen;
+               Der_type endtime_type;
+               e = der_match_tag_and_length(p, len, ASN1_C_CONTEXT, &endtime_type, 7, &endtime_datalen, &l);
+               if (e == 0 && endtime_type != CONS) {
+                   e = ASN1_BAD_ID;
+               }
+               if (e)
+                   goto fail;
+               p += l;
+               len -= l;
+               ret += l;
+               endtime_oldlen = len;
+               if (endtime_datalen > len) {
+                   e = ASN1_OVERRUN;
+                   goto fail;
+               }
+               len = endtime_datalen;
+               e = decode_KerberosTime(p, len, &(data)->endtime, &l);
                if (e)
+                   goto fail;
+               p += l;
+               len -= l;
+               ret += l;
+               len = endtime_oldlen - endtime_datalen;
+           }
+           {
+               size_t renew_till_datalen, renew_till_oldlen;
+               Der_type renew_till_type;
+               e = der_match_tag_and_length(p, len, ASN1_C_CONTEXT, &renew_till_type, 8, &renew_till_datalen, &l);
+               if (e == 0 && renew_till_type != CONS) {
+                   e = ASN1_BAD_ID;
+               }
+               if (e) {
                    (data)->renew_till = NULL;
-               else {
+               } else {
+                   (data)->renew_till = calloc(1, sizeof(*(data)->renew_till));
+                   if ((data)->renew_till == NULL) {
+                       e = ENOMEM;
+                       goto fail;
+                   }
                    p += l;
                    len -= l;
                    ret += l;
-                   e = der_get_length(p, len, &newlen, &l);
-                   FORW;
-                   {
-                       int dce_fix;
-                       oldlen = len;
-                       if ((dce_fix = fix_dce(newlen, &len)) < 0)
-                           return ASN1_BAD_FORMAT;
-                       (data)->renew_till =
-                           malloc(sizeof(*(data)->renew_till));
-                       if ((data)->renew_till == NULL)
-                           return ENOMEM;
-                       e = decode_KerberosTime(p, len, (data)->renew_till,
-                                               &l);
-                       FORW;
-                       if (dce_fix) {
-                           e = der_match_tag_and_length(p, len,
-                                                        (Der_class) 0,
-                                                        (Der_type) 0, 0,
-                                                        &reallen, &l);
-                           FORW;
-                       } else
-                           len = oldlen - newlen;
+                   renew_till_oldlen = len;
+                   if (renew_till_datalen > len) {
+                       e = ASN1_OVERRUN;
+                       goto fail;
                    }
+                   len = renew_till_datalen;
+                   e = decode_KerberosTime(p, len, (data)->renew_till, &l);
+                   if (e)
+                       goto fail;
+                   p += l;
+                   len -= l;
+                   ret += l;
+                   len = renew_till_oldlen - renew_till_datalen;
                }
            }
            {
-               size_t newlen, oldlen;
-
-               e = der_match_tag(p, len, Der_CONTEXT, CONS, 9, &l);
-               if (e)
+               size_t caddr_datalen, caddr_oldlen;
+               Der_type caddr_type;
+               e = der_match_tag_and_length(p, len, ASN1_C_CONTEXT, &caddr_type, 9, &caddr_datalen, &l);
+               if (e == 0 && caddr_type != CONS) {
+                   e = ASN1_BAD_ID;
+               }
+               if (e) {
                    (data)->caddr = NULL;
-               else {
+               } else {
+                   (data)->caddr = calloc(1, sizeof(*(data)->caddr));
+                   if ((data)->caddr == NULL) {
+                       e = ENOMEM;
+                       goto fail;
+                   }
                    p += l;
                    len -= l;
                    ret += l;
-                   e = der_get_length(p, len, &newlen, &l);
-                   FORW;
-                   {
-                       int dce_fix;
-                       oldlen = len;
-                       if ((dce_fix = fix_dce(newlen, &len)) < 0)
-                           return ASN1_BAD_FORMAT;
-                       (data)->caddr = malloc(sizeof(*(data)->caddr));
-                       if ((data)->caddr == NULL)
-                           return ENOMEM;
-                       e = decode_HostAddresses(p, len, (data)->caddr, &l);
-                       FORW;
-                       if (dce_fix) {
-                           e = der_match_tag_and_length(p, len,
-                                                        (Der_class) 0,
-                                                        (Der_type) 0, 0,
-                                                        &reallen, &l);
-                           FORW;
-                       } else
-                           len = oldlen - newlen;
+                   caddr_oldlen = len;
+                   if (caddr_datalen > len) {
+                       e = ASN1_OVERRUN;
+                       goto fail;
                    }
+                   len = caddr_datalen;
+                   e = decode_HostAddresses(p, len, (data)->caddr, &l);
+                   if (e)
+                       goto fail;
+                   p += l;
+                   len -= l;
+                   ret += l;
+                   len = caddr_oldlen - caddr_datalen;
                }
            }
            {
-               size_t newlen, oldlen;
-
-               e = der_match_tag(p, len, Der_CONTEXT, CONS, 10, &l);
-               if (e)
+               size_t authorization_data_datalen, authorization_data_oldlen;
+               Der_type authorization_data_type;
+               e = der_match_tag_and_length(p, len, ASN1_C_CONTEXT, &authorization_data_type, 10, &authorization_data_datalen, &l);
+               if (e == 0 && authorization_data_type != CONS) {
+                   e = ASN1_BAD_ID;
+               }
+               if (e) {
                    (data)->authorization_data = NULL;
-               else {
+               } else {
+                   (data)->authorization_data = calloc(1, sizeof(*(data)->authorization_data));
+                   if ((data)->authorization_data == NULL) {
+                       e = ENOMEM;
+                       goto fail;
+                   }
                    p += l;
                    len -= l;
                    ret += l;
-                   e = der_get_length(p, len, &newlen, &l);
-                   FORW;
-                   {
-                       int dce_fix;
-                       oldlen = len;
-                       if ((dce_fix = fix_dce(newlen, &len)) < 0)
-                           return ASN1_BAD_FORMAT;
-                       (data)->authorization_data =
-                           malloc(sizeof(*(data)->authorization_data));
-                       if ((data)->authorization_data == NULL)
-                           return ENOMEM;
-                       e = decode_AuthorizationData(p, len,
-                                                    (data)->
-                                                    authorization_data, &l);
-                       FORW;
-                       if (dce_fix) {
-                           e = der_match_tag_and_length(p, len,
-                                                        (Der_class) 0,
-                                                        (Der_type) 0, 0,
-                                                        &reallen, &l);
-                           FORW;
-                       } else
-                           len = oldlen - newlen;
+                   authorization_data_oldlen = len;
+                   if (authorization_data_datalen > len) {
+                       e = ASN1_OVERRUN;
+                       goto fail;
                    }
+                   len = authorization_data_datalen;
+                   e = decode_AuthorizationData(p, len, (data)->authorization_data, &l);
+                   if (e)
+                       goto fail;
+                   p += l;
+                   len -= l;
+                   ret += l;
+                   len = authorization_data_oldlen - authorization_data_datalen;
                }
            }
-           if (dce_fix) {
-               e = der_match_tag_and_length(p, len, (Der_class) 0,
-                                            (Der_type) 0, 0, &reallen, &l);
-               FORW;
-           }
-       }
-       if (dce_fix) {
-           e = der_match_tag_and_length(p, len, (Der_class) 0, (Der_type) 0,
-                                        0, &reallen, &l);
-           FORW;
+           len = Top_Tag_oldlen - Top_Tag_datalen;
        }
+       len = Top_oldlen - Top_datalen;
     }
     if (size)
        *size = ret;
     return 0;
-  fail:
+fail:
     free_EncTicketPart(data);
     return e;
 }
@@ -1794,19 +2513,23 @@ free_EncTicketPart(EncTicketPart * data)
     if ((data)->starttime) {
        free_KerberosTime((data)->starttime);
        free((data)->starttime);
+       (data)->starttime = NULL;
     }
     free_KerberosTime(&(data)->endtime);
     if ((data)->renew_till) {
        free_KerberosTime((data)->renew_till);
        free((data)->renew_till);
+       (data)->renew_till = NULL;
     }
     if ((data)->caddr) {
        free_HostAddresses((data)->caddr);
        free((data)->caddr);
+       (data)->caddr = NULL;
     }
     if ((data)->authorization_data) {
        free_AuthorizationData((data)->authorization_data);
        free((data)->authorization_data);
+       (data)->authorization_data = NULL;
     }
 }
 
@@ -1815,130 +2538,145 @@ length_EncTicketPart(const EncTicketPart * data)
 {
     size_t ret = 0;
     {
-       int oldret = ret;
+       size_t Top_tag_tag_oldret = ret;
        ret = 0;
        ret += length_TicketFlags(&(data)->flags);
-       ret += 1 + length_len(ret) + oldret;
+       ret += 1 + der_length_len(ret);
+       ret += Top_tag_tag_oldret;
     }
     {
-       int oldret = ret;
+       size_t Top_tag_tag_oldret = ret;
        ret = 0;
        ret += length_EncryptionKey(&(data)->key);
-       ret += 1 + length_len(ret) + oldret;
+       ret += 1 + der_length_len(ret);
+       ret += Top_tag_tag_oldret;
     }
     {
-       int oldret = ret;
+       size_t Top_tag_tag_oldret = ret;
        ret = 0;
        ret += length_Realm(&(data)->crealm);
-       ret += 1 + length_len(ret) + oldret;
+       ret += 1 + der_length_len(ret);
+       ret += Top_tag_tag_oldret;
     }
     {
-       int oldret = ret;
+       size_t Top_tag_tag_oldret = ret;
        ret = 0;
        ret += length_PrincipalName(&(data)->cname);
-       ret += 1 + length_len(ret) + oldret;
+       ret += 1 + der_length_len(ret);
+       ret += Top_tag_tag_oldret;
     }
     {
-       int oldret = ret;
+       size_t Top_tag_tag_oldret = ret;
        ret = 0;
        ret += length_TransitedEncoding(&(data)->transited);
-       ret += 1 + length_len(ret) + oldret;
+       ret += 1 + der_length_len(ret);
+       ret += Top_tag_tag_oldret;
     }
     {
-       int oldret = ret;
+       size_t Top_tag_tag_oldret = ret;
        ret = 0;
        ret += length_KerberosTime(&(data)->authtime);
-       ret += 1 + length_len(ret) + oldret;
+       ret += 1 + der_length_len(ret);
+       ret += Top_tag_tag_oldret;
     }
     if ((data)->starttime) {
-       int oldret = ret;
+       size_t Top_tag_tag_oldret = ret;
        ret = 0;
        ret += length_KerberosTime((data)->starttime);
-       ret += 1 + length_len(ret) + oldret;
-    }
-    {
-       int oldret = ret;
+       ret += 1 + der_length_len(ret);
+       ret += Top_tag_tag_oldret;
+    } {
+       size_t Top_tag_tag_oldret = ret;
        ret = 0;
        ret += length_KerberosTime(&(data)->endtime);
-       ret += 1 + length_len(ret) + oldret;
+       ret += 1 + der_length_len(ret);
+       ret += Top_tag_tag_oldret;
     }
     if ((data)->renew_till) {
-       int oldret = ret;
+       size_t Top_tag_tag_oldret = ret;
        ret = 0;
        ret += length_KerberosTime((data)->renew_till);
-       ret += 1 + length_len(ret) + oldret;
+       ret += 1 + der_length_len(ret);
+       ret += Top_tag_tag_oldret;
     }
     if ((data)->caddr) {
-       int oldret = ret;
+       size_t Top_tag_tag_oldret = ret;
        ret = 0;
        ret += length_HostAddresses((data)->caddr);
-       ret += 1 + length_len(ret) + oldret;
+       ret += 1 + der_length_len(ret);
+       ret += Top_tag_tag_oldret;
     }
     if ((data)->authorization_data) {
-       int oldret = ret;
+       size_t Top_tag_tag_oldret = ret;
        ret = 0;
        ret += length_AuthorizationData((data)->authorization_data);
-       ret += 1 + length_len(ret) + oldret;
+       ret += 1 + der_length_len(ret);
+       ret += Top_tag_tag_oldret;
     }
-    ret += 1 + length_len(ret);
-    ret += 1 + length_len(ret);
+    ret += 1 + der_length_len(ret);
+    ret += 1 + der_length_len(ret);
     return ret;
 }
 
 int
 copy_EncTicketPart(const EncTicketPart * from, EncTicketPart * to)
 {
+    memset(to, 0, sizeof(*to));
     if (copy_TicketFlags(&(from)->flags, &(to)->flags))
-       return ENOMEM;
+       goto fail;
     if (copy_EncryptionKey(&(from)->key, &(to)->key))
-       return ENOMEM;
+       goto fail;
     if (copy_Realm(&(from)->crealm, &(to)->crealm))
-       return ENOMEM;
+       goto fail;
     if (copy_PrincipalName(&(from)->cname, &(to)->cname))
-       return ENOMEM;
+       goto fail;
     if (copy_TransitedEncoding(&(from)->transited, &(to)->transited))
-       return ENOMEM;
+       goto fail;
     if (copy_KerberosTime(&(from)->authtime, &(to)->authtime))
-       return ENOMEM;
+       goto fail;
     if ((from)->starttime) {
        (to)->starttime = malloc(sizeof(*(to)->starttime));
        if ((to)->starttime == NULL)
-           return ENOMEM;
+           goto fail;
        if (copy_KerberosTime((from)->starttime, (to)->starttime))
-           return ENOMEM;
+           goto fail;
     } else
        (to)->starttime = NULL;
     if (copy_KerberosTime(&(from)->endtime, &(to)->endtime))
-       return ENOMEM;
+       goto fail;
     if ((from)->renew_till) {
        (to)->renew_till = malloc(sizeof(*(to)->renew_till));
        if ((to)->renew_till == NULL)
-           return ENOMEM;
+           goto fail;
        if (copy_KerberosTime((from)->renew_till, (to)->renew_till))
-           return ENOMEM;
+           goto fail;
     } else
        (to)->renew_till = NULL;
     if ((from)->caddr) {
        (to)->caddr = malloc(sizeof(*(to)->caddr));
        if ((to)->caddr == NULL)
-           return ENOMEM;
+           goto fail;
        if (copy_HostAddresses((from)->caddr, (to)->caddr))
-           return ENOMEM;
+           goto fail;
     } else
        (to)->caddr = NULL;
     if ((from)->authorization_data) {
        (to)->authorization_data = malloc(sizeof(*(to)->authorization_data));
        if ((to)->authorization_data == NULL)
-           return ENOMEM;
-       if (copy_AuthorizationData
-           ((from)->authorization_data, (to)->authorization_data))
-           return ENOMEM;
+           goto fail;
+       if (copy_AuthorizationData((from)->authorization_data, (to)->authorization_data))
+           goto fail;
     } else
        (to)->authorization_data = NULL;
     return 0;
+fail:
+    free_EncTicketPart(to);
+    return ENOMEM;
 }
 
-/* Generated from /home/lha/src/cvs/heimdal/lib/asn1/k5.asn1 */
+
+
+/* Generated from ./krb5.asn1 */
 /* Do not edit */
 
 #include <stdio.h>
@@ -1946,43 +2684,73 @@ copy_EncTicketPart(const EncTicketPart * from, EncTicketPart * to)
 #include <time.h>
 #include <string.h>
 #include <errno.h>
+#include <limits.h>
 #include <asn1_err.h>
 
-#define BACK if (e) return e; p -= l; len -= l; ret += l
-
 int
-encode_KerberosTime(unsigned char *p, size_t len, const KerberosTime * data,
-                   size_t * size)
+encode_KerberosTime(unsigned char *p, size_t len, const KerberosTime * data, size_t * size)
 {
     size_t ret = 0;
     size_t l;
     int i, e;
 
     i = 0;
-    e = encode_generalized_time(p, len, data, &l);
-    BACK;
+    e = der_put_generalized_time(p, len, data, &l);
+    if (e)
+       return e;
+    p -= l;
+    len -= l;
+    ret += l;
+
+    e = der_put_length_and_tag(p, len, ret, ASN1_C_UNIV, PRIM, UT_GeneralizedTime, &l);
+    if (e)
+       return e;
+    p -= l;
+    len -= l;
+    ret += l;
+
     *size = ret;
     return 0;
 }
 
-#define FORW if(e) goto fail; p += l; len -= l; ret += l
-
 int
-decode_KerberosTime(const unsigned char *p, size_t len, KerberosTime * data,
-                   size_t * size)
+decode_KerberosTime(const unsigned char *p, size_t len, KerberosTime * data, size_t * size)
 {
-    size_t ret = 0, reallen;
+    size_t ret = 0;
     size_t l;
     int e;
 
     memset(data, 0, sizeof(*data));
-    reallen = 0;
-    e = decode_generalized_time(p, len, data, &l);
-    FORW;
+    {
+       size_t Top_datalen, Top_oldlen;
+       Der_type Top_type;
+       e = der_match_tag_and_length(p, len, ASN1_C_UNIV, &Top_type, UT_GeneralizedTime, &Top_datalen, &l);
+       if (e == 0 && Top_type != PRIM) {
+           e = ASN1_BAD_ID;
+       }
+       if (e)
+           goto fail;
+       p += l;
+       len -= l;
+       ret += l;
+       Top_oldlen = len;
+       if (Top_datalen > len) {
+           e = ASN1_OVERRUN;
+           goto fail;
+       }
+       len = Top_datalen;
+       e = der_get_generalized_time(p, len, data, &l);
+       if (e)
+           goto fail;
+       p += l;
+       len -= l;
+       ret += l;
+       len = Top_oldlen - Top_datalen;
+    }
     if (size)
        *size = ret;
     return 0;
-  fail:
+fail:
     free_KerberosTime(data);
     return e;
 }
@@ -1996,18 +2764,22 @@ size_t
 length_KerberosTime(const KerberosTime * data)
 {
     size_t ret = 0;
-    ret += length_generalized_time(data);
+    ret += der_length_generalized_time(data);
+    ret += 1 + der_length_len(ret);
     return ret;
 }
 
 int
 copy_KerberosTime(const KerberosTime * from, KerberosTime * to)
 {
+    memset(to, 0, sizeof(*to));
     *(to) = *(from);
     return 0;
 }
 
-/* Generated from /home/lha/src/cvs/heimdal/lib/asn1/k5.asn1 */
+
+
+/* Generated from ./krb5.asn1 */
 /* Do not edit */
 
 #include <stdio.h>
@@ -2015,130 +2787,179 @@ copy_KerberosTime(const KerberosTime * from, KerberosTime * to)
 #include <time.h>
 #include <string.h>
 #include <errno.h>
+#include <limits.h>
 #include <asn1_err.h>
 
-#define BACK if (e) return e; p -= l; len -= l; ret += l
-
 int
-encode_TransitedEncoding(unsigned char *p, size_t len,
-                        const TransitedEncoding * data, size_t * size)
+encode_TransitedEncoding(unsigned char *p, size_t len, const TransitedEncoding * data, size_t * size)
 {
     size_t ret = 0;
     size_t l;
     int i, e;
 
     i = 0;
+/* contents */
     {
-       int oldret = ret;
+       size_t Top_tag_oldret = ret;
        ret = 0;
-       e = encode_octet_string(p, len, &(data)->contents, &l);
-       BACK;
-       e = der_put_length_and_tag(p, len, ret, Der_CONTEXT, CONS, 1, &l);
-       BACK;
-       ret += oldret;
-    }
+       e = der_put_octet_string(p, len, &(data)->contents, &l);
+       if (e)
+           return e;
+       p -= l;
+       len -= l;
+       ret += l;
+
+       e = der_put_length_and_tag(p, len, ret, ASN1_C_UNIV, PRIM, UT_OctetString, &l);
+       if (e)
+           return e;
+       p -= l;
+       len -= l;
+       ret += l;
+
+       e = der_put_length_and_tag(p, len, ret, ASN1_C_CONTEXT, CONS, 1, &l);
+       if (e)
+           return e;
+       p -= l;
+       len -= l;
+       ret += l;
+
+       ret += Top_tag_oldret;
+    }
+/* tr-type */
     {
-       int oldret = ret;
+       size_t Top_tag_oldret = ret;
        ret = 0;
-       e = encode_integer(p, len, &(data)->tr_type, &l);
-       BACK;
-       e = der_put_length_and_tag(p, len, ret, Der_CONTEXT, CONS, 0, &l);
-       BACK;
-       ret += oldret;
-    }
-    e = der_put_length_and_tag(p, len, ret, UNIV, CONS, UT_Sequence, &l);
-    BACK;
+       e = encode_krb5int32(p, len, &(data)->tr_type, &l);
+       if (e)
+           return e;
+       p -= l;
+       len -= l;
+       ret += l;
+
+       e = der_put_length_and_tag(p, len, ret, ASN1_C_CONTEXT, CONS, 0, &l);
+       if (e)
+           return e;
+       p -= l;
+       len -= l;
+       ret += l;
+
+       ret += Top_tag_oldret;
+    }
+    e = der_put_length_and_tag(p, len, ret, ASN1_C_UNIV, CONS, UT_Sequence, &l);
+    if (e)
+       return e;
+    p -= l;
+    len -= l;
+    ret += l;
+
     *size = ret;
     return 0;
 }
 
-#define FORW if(e) goto fail; p += l; len -= l; ret += l
-
 int
-decode_TransitedEncoding(const unsigned char *p, size_t len,
-                        TransitedEncoding * data, size_t * size)
+decode_TransitedEncoding(const unsigned char *p, size_t len, TransitedEncoding * data, size_t * size)
 {
-    size_t ret = 0, reallen;
+    size_t ret = 0;
     size_t l;
     int e;
 
     memset(data, 0, sizeof(*data));
-    reallen = 0;
-    e = der_match_tag_and_length(p, len, UNIV, CONS, UT_Sequence, &reallen,
-                                &l);
-    FORW;
-    {
-       int dce_fix;
-       if ((dce_fix = fix_dce(reallen, &len)) < 0)
-           return ASN1_BAD_FORMAT;
+    {
+       size_t Top_datalen, Top_oldlen;
+       Der_type Top_type;
+       e = der_match_tag_and_length(p, len, ASN1_C_UNIV, &Top_type, UT_Sequence, &Top_datalen, &l);
+       if (e == 0 && Top_type != CONS) {
+           e = ASN1_BAD_ID;
+       }
+       if (e)
+           goto fail;
+       p += l;
+       len -= l;
+       ret += l;
+       Top_oldlen = len;
+       if (Top_datalen > len) {
+           e = ASN1_OVERRUN;
+           goto fail;
+       }
+       len = Top_datalen;
        {
-           size_t newlen, oldlen;
-
-           e = der_match_tag(p, len, Der_CONTEXT, CONS, 0, &l);
+           size_t tr_type_datalen, tr_type_oldlen;
+           Der_type tr_type_type;
+           e = der_match_tag_and_length(p, len, ASN1_C_CONTEXT, &tr_type_type, 0, &tr_type_datalen, &l);
+           if (e == 0 && tr_type_type != CONS) {
+               e = ASN1_BAD_ID;
+           }
            if (e)
-               return e;
-           else {
-               p += l;
-               len -= l;
-               ret += l;
-               e = der_get_length(p, len, &newlen, &l);
-               FORW;
-               {
-                   int dce_fix;
-                   oldlen = len;
-                   if ((dce_fix = fix_dce(newlen, &len)) < 0)
-                       return ASN1_BAD_FORMAT;
-                   e = decode_integer(p, len, &(data)->tr_type, &l);
-                   FORW;
-                   if (dce_fix) {
-                       e = der_match_tag_and_length(p, len, (Der_class) 0,
-                                                    (Der_type) 0, 0,
-                                                    &reallen, &l);
-                       FORW;
-                   } else
-                       len = oldlen - newlen;
-               }
+               goto fail;
+           p += l;
+           len -= l;
+           ret += l;
+           tr_type_oldlen = len;
+           if (tr_type_datalen > len) {
+               e = ASN1_OVERRUN;
+               goto fail;
            }
+           len = tr_type_datalen;
+           e = decode_krb5int32(p, len, &(data)->tr_type, &l);
+           if (e)
+               goto fail;
+           p += l;
+           len -= l;
+           ret += l;
+           len = tr_type_oldlen - tr_type_datalen;
        }
        {
-           size_t newlen, oldlen;
-
-           e = der_match_tag(p, len, Der_CONTEXT, CONS, 1, &l);
+           size_t contents_datalen, contents_oldlen;
+           Der_type contents_type;
+           e = der_match_tag_and_length(p, len, ASN1_C_CONTEXT, &contents_type, 1, &contents_datalen, &l);
+           if (e == 0 && contents_type != CONS) {
+               e = ASN1_BAD_ID;
+           }
            if (e)
-               return e;
-           else {
+               goto fail;
+           p += l;
+           len -= l;
+           ret += l;
+           contents_oldlen = len;
+           if (contents_datalen > len) {
+               e = ASN1_OVERRUN;
+               goto fail;
+           }
+           len = contents_datalen;
+           {
+               size_t contents_Tag_datalen, contents_Tag_oldlen;
+               Der_type contents_Tag_type;
+               e = der_match_tag_and_length(p, len, ASN1_C_UNIV, &contents_Tag_type, UT_OctetString, &contents_Tag_datalen, &l);
+               if (e == 0 && contents_Tag_type != PRIM) {
+                   e = ASN1_BAD_ID;
+               }
+               if (e)
+                   goto fail;
                p += l;
                len -= l;
                ret += l;
-               e = der_get_length(p, len, &newlen, &l);
-               FORW;
-               {
-                   int dce_fix;
-                   oldlen = len;
-                   if ((dce_fix = fix_dce(newlen, &len)) < 0)
-                       return ASN1_BAD_FORMAT;
-                   e = decode_octet_string(p, len, &(data)->contents, &l);
-                   FORW;
-                   if (dce_fix) {
-                       e = der_match_tag_and_length(p, len, (Der_class) 0,
-                                                    (Der_type) 0, 0,
-                                                    &reallen, &l);
-                       FORW;
-                   } else
-                       len = oldlen - newlen;
+               contents_Tag_oldlen = len;
+               if (contents_Tag_datalen > len) {
+                   e = ASN1_OVERRUN;
+                   goto fail;
                }
+               len = contents_Tag_datalen;
+               e = der_get_octet_string(p, len, &(data)->contents, &l);
+               if (e)
+                   goto fail;
+               p += l;
+               len -= l;
+               ret += l;
+               len = contents_Tag_oldlen - contents_Tag_datalen;
            }
+           len = contents_oldlen - contents_datalen;
        }
-       if (dce_fix) {
-           e = der_match_tag_and_length(p, len, (Der_class) 0, (Der_type) 0,
-                                        0, &reallen, &l);
-           FORW;
-       }
+       len = Top_oldlen - Top_datalen;
     }
     if (size)
        *size = ret;
     return 0;
-  fail:
+fail:
     free_TransitedEncoding(data);
     return e;
 }
@@ -2146,7 +2967,8 @@ decode_TransitedEncoding(const unsigned char *p, size_t len,
 void
 free_TransitedEncoding(TransitedEncoding * data)
 {
-    free_octet_string(&(data)->contents);
+    free_krb5int32(&(data)->tr_type);
+    der_free_octet_string(&(data)->contents);
 }
 
 size_t
@@ -2154,31 +2976,41 @@ length_TransitedEncoding(const TransitedEncoding * data)
 {
     size_t ret = 0;
     {
-       int oldret = ret;
+       size_t Top_tag_oldret = ret;
        ret = 0;
-       ret += length_integer(&(data)->tr_type);
-       ret += 1 + length_len(ret) + oldret;
+       ret += length_krb5int32(&(data)->tr_type);
+       ret += 1 + der_length_len(ret);
+       ret += Top_tag_oldret;
     }
     {
-       int oldret = ret;
+       size_t Top_tag_oldret = ret;
        ret = 0;
-       ret += length_octet_string(&(data)->contents);
-       ret += 1 + length_len(ret) + oldret;
+       ret += der_length_octet_string(&(data)->contents);
+       ret += 1 + der_length_len(ret);
+       ret += 1 + der_length_len(ret);
+       ret += Top_tag_oldret;
     }
-    ret += 1 + length_len(ret);
+    ret += 1 + der_length_len(ret);
     return ret;
 }
 
 int
 copy_TransitedEncoding(const TransitedEncoding * from, TransitedEncoding * to)
 {
-    *(&(to)->tr_type) = *(&(from)->tr_type);
-    if (copy_octet_string(&(from)->contents, &(to)->contents))
-       return ENOMEM;
+    memset(to, 0, sizeof(*to));
+    if (copy_krb5int32(&(from)->tr_type, &(to)->tr_type))
+       goto fail;
+    if (der_copy_octet_string(&(from)->contents, &(to)->contents))
+       goto fail;
     return 0;
+fail:
+    free_TransitedEncoding(to);
+    return ENOMEM;
 }
 
-/* Generated from /home/lha/src/cvs/heimdal/lib/asn1/k5.asn1 */
+
+
+/* Generated from ./krb5.asn1 */
 /* Do not edit */
 
 #include <stdio.h>
@@ -2186,130 +3018,179 @@ copy_TransitedEncoding(const TransitedEncoding * from, TransitedEncoding * to)
 #include <time.h>
 #include <string.h>
 #include <errno.h>
+#include <limits.h>
 #include <asn1_err.h>
 
-#define BACK if (e) return e; p -= l; len -= l; ret += l
-
 int
-encode_EncryptionKey(unsigned char *p, size_t len, const EncryptionKey * data,
-                    size_t * size)
+encode_EncryptionKey(unsigned char *p, size_t len, const EncryptionKey * data, size_t * size)
 {
     size_t ret = 0;
     size_t l;
     int i, e;
 
     i = 0;
+/* keyvalue */
     {
-       int oldret = ret;
+       size_t Top_tag_oldret = ret;
        ret = 0;
-       e = encode_octet_string(p, len, &(data)->keyvalue, &l);
-       BACK;
-       e = der_put_length_and_tag(p, len, ret, Der_CONTEXT, CONS, 1, &l);
-       BACK;
-       ret += oldret;
-    }
+       e = der_put_octet_string(p, len, &(data)->keyvalue, &l);
+       if (e)
+           return e;
+       p -= l;
+       len -= l;
+       ret += l;
+
+       e = der_put_length_and_tag(p, len, ret, ASN1_C_UNIV, PRIM, UT_OctetString, &l);
+       if (e)
+           return e;
+       p -= l;
+       len -= l;
+       ret += l;
+
+       e = der_put_length_and_tag(p, len, ret, ASN1_C_CONTEXT, CONS, 1, &l);
+       if (e)
+           return e;
+       p -= l;
+       len -= l;
+       ret += l;
+
+       ret += Top_tag_oldret;
+    }
+/* keytype */
     {
-       int oldret = ret;
+       size_t Top_tag_oldret = ret;
        ret = 0;
-       e = encode_integer(p, len, &(data)->keytype, &l);
-       BACK;
-       e = der_put_length_and_tag(p, len, ret, Der_CONTEXT, CONS, 0, &l);
-       BACK;
-       ret += oldret;
-    }
-    e = der_put_length_and_tag(p, len, ret, UNIV, CONS, UT_Sequence, &l);
-    BACK;
+       e = encode_krb5int32(p, len, &(data)->keytype, &l);
+       if (e)
+           return e;
+       p -= l;
+       len -= l;
+       ret += l;
+
+       e = der_put_length_and_tag(p, len, ret, ASN1_C_CONTEXT, CONS, 0, &l);
+       if (e)
+           return e;
+       p -= l;
+       len -= l;
+       ret += l;
+
+       ret += Top_tag_oldret;
+    }
+    e = der_put_length_and_tag(p, len, ret, ASN1_C_UNIV, CONS, UT_Sequence, &l);
+    if (e)
+       return e;
+    p -= l;
+    len -= l;
+    ret += l;
+
     *size = ret;
     return 0;
 }
 
-#define FORW if(e) goto fail; p += l; len -= l; ret += l
-
 int
-decode_EncryptionKey(const unsigned char *p, size_t len, EncryptionKey * data,
-                    size_t * size)
+decode_EncryptionKey(const unsigned char *p, size_t len, EncryptionKey * data, size_t * size)
 {
-    size_t ret = 0, reallen;
+    size_t ret = 0;
     size_t l;
     int e;
 
     memset(data, 0, sizeof(*data));
-    reallen = 0;
-    e = der_match_tag_and_length(p, len, UNIV, CONS, UT_Sequence, &reallen,
-                                &l);
-    FORW;
-    {
-       int dce_fix;
-       if ((dce_fix = fix_dce(reallen, &len)) < 0)
-           return ASN1_BAD_FORMAT;
+    {
+       size_t Top_datalen, Top_oldlen;
+       Der_type Top_type;
+       e = der_match_tag_and_length(p, len, ASN1_C_UNIV, &Top_type, UT_Sequence, &Top_datalen, &l);
+       if (e == 0 && Top_type != CONS) {
+           e = ASN1_BAD_ID;
+       }
+       if (e)
+           goto fail;
+       p += l;
+       len -= l;
+       ret += l;
+       Top_oldlen = len;
+       if (Top_datalen > len) {
+           e = ASN1_OVERRUN;
+           goto fail;
+       }
+       len = Top_datalen;
        {
-           size_t newlen, oldlen;
-
-           e = der_match_tag(p, len, Der_CONTEXT, CONS, 0, &l);
+           size_t keytype_datalen, keytype_oldlen;
+           Der_type keytype_type;
+           e = der_match_tag_and_length(p, len, ASN1_C_CONTEXT, &keytype_type, 0, &keytype_datalen, &l);
+           if (e == 0 && keytype_type != CONS) {
+               e = ASN1_BAD_ID;
+           }
            if (e)
-               return e;
-           else {
-               p += l;
-               len -= l;
-               ret += l;
-               e = der_get_length(p, len, &newlen, &l);
-               FORW;
-               {
-                   int dce_fix;
-                   oldlen = len;
-                   if ((dce_fix = fix_dce(newlen, &len)) < 0)
-                       return ASN1_BAD_FORMAT;
-                   e = decode_integer(p, len, &(data)->keytype, &l);
-                   FORW;
-                   if (dce_fix) {
-                       e = der_match_tag_and_length(p, len, (Der_class) 0,
-                                                    (Der_type) 0, 0,
-                                                    &reallen, &l);
-                       FORW;
-                   } else
-                       len = oldlen - newlen;
-               }
+               goto fail;
+           p += l;
+           len -= l;
+           ret += l;
+           keytype_oldlen = len;
+           if (keytype_datalen > len) {
+               e = ASN1_OVERRUN;
+               goto fail;
            }
+           len = keytype_datalen;
+           e = decode_krb5int32(p, len, &(data)->keytype, &l);
+           if (e)
+               goto fail;
+           p += l;
+           len -= l;
+           ret += l;
+           len = keytype_oldlen - keytype_datalen;
        }
        {
-           size_t newlen, oldlen;
-
-           e = der_match_tag(p, len, Der_CONTEXT, CONS, 1, &l);
+           size_t keyvalue_datalen, keyvalue_oldlen;
+           Der_type keyvalue_type;
+           e = der_match_tag_and_length(p, len, ASN1_C_CONTEXT, &keyvalue_type, 1, &keyvalue_datalen, &l);
+           if (e == 0 && keyvalue_type != CONS) {
+               e = ASN1_BAD_ID;
+           }
            if (e)
-               return e;
-           else {
+               goto fail;
+           p += l;
+           len -= l;
+           ret += l;
+           keyvalue_oldlen = len;
+           if (keyvalue_datalen > len) {
+               e = ASN1_OVERRUN;
+               goto fail;
+           }
+           len = keyvalue_datalen;
+           {
+               size_t keyvalue_Tag_datalen, keyvalue_Tag_oldlen;
+               Der_type keyvalue_Tag_type;
+               e = der_match_tag_and_length(p, len, ASN1_C_UNIV, &keyvalue_Tag_type, UT_OctetString, &keyvalue_Tag_datalen, &l);
+               if (e == 0 && keyvalue_Tag_type != PRIM) {
+                   e = ASN1_BAD_ID;
+               }
+               if (e)
+                   goto fail;
                p += l;
                len -= l;
                ret += l;
-               e = der_get_length(p, len, &newlen, &l);
-               FORW;
-               {
-                   int dce_fix;
-                   oldlen = len;
-                   if ((dce_fix = fix_dce(newlen, &len)) < 0)
-                       return ASN1_BAD_FORMAT;
-                   e = decode_octet_string(p, len, &(data)->keyvalue, &l);
-                   FORW;
-                   if (dce_fix) {
-                       e = der_match_tag_and_length(p, len, (Der_class) 0,
-                                                    (Der_type) 0, 0,
-                                                    &reallen, &l);
-                       FORW;
-                   } else
-                       len = oldlen - newlen;
+               keyvalue_Tag_oldlen = len;
+               if (keyvalue_Tag_datalen > len) {
+                   e = ASN1_OVERRUN;
+                   goto fail;
                }
+               len = keyvalue_Tag_datalen;
+               e = der_get_octet_string(p, len, &(data)->keyvalue, &l);
+               if (e)
+                   goto fail;
+               p += l;
+               len -= l;
+               ret += l;
+               len = keyvalue_Tag_oldlen - keyvalue_Tag_datalen;
            }
+           len = keyvalue_oldlen - keyvalue_datalen;
        }
-       if (dce_fix) {
-           e = der_match_tag_and_length(p, len, (Der_class) 0, (Der_type) 0,
-                                        0, &reallen, &l);
-           FORW;
-       }
+       len = Top_oldlen - Top_datalen;
     }
     if (size)
        *size = ret;
     return 0;
-  fail:
+fail:
     free_EncryptionKey(data);
     return e;
 }
@@ -2317,7 +3198,8 @@ decode_EncryptionKey(const unsigned char *p, size_t len, EncryptionKey * data,
 void
 free_EncryptionKey(EncryptionKey * data)
 {
-    free_octet_string(&(data)->keyvalue);
+    free_krb5int32(&(data)->keytype);
+    der_free_octet_string(&(data)->keyvalue);
 }
 
 size_t
@@ -2325,31 +3207,41 @@ length_EncryptionKey(const EncryptionKey * data)
 {
     size_t ret = 0;
     {
-       int oldret = ret;
+       size_t Top_tag_oldret = ret;
        ret = 0;
-       ret += length_integer(&(data)->keytype);
-       ret += 1 + length_len(ret) + oldret;
+       ret += length_krb5int32(&(data)->keytype);
+       ret += 1 + der_length_len(ret);
+       ret += Top_tag_oldret;
     }
     {
-       int oldret = ret;
+       size_t Top_tag_oldret = ret;
        ret = 0;
-       ret += length_octet_string(&(data)->keyvalue);
-       ret += 1 + length_len(ret) + oldret;
+       ret += der_length_octet_string(&(data)->keyvalue);
+       ret += 1 + der_length_len(ret);
+       ret += 1 + der_length_len(ret);
+       ret += Top_tag_oldret;
     }
-    ret += 1 + length_len(ret);
+    ret += 1 + der_length_len(ret);
     return ret;
 }
 
 int
 copy_EncryptionKey(const EncryptionKey * from, EncryptionKey * to)
 {
-    *(&(to)->keytype) = *(&(from)->keytype);
-    if (copy_octet_string(&(from)->keyvalue, &(to)->keyvalue))
-       return ENOMEM;
+    memset(to, 0, sizeof(*to));
+    if (copy_krb5int32(&(from)->keytype, &(to)->keytype))
+       goto fail;
+    if (der_copy_octet_string(&(from)->keyvalue, &(to)->keyvalue))
+       goto fail;
     return 0;
+fail:
+    free_EncryptionKey(to);
+    return ENOMEM;
 }
 
-/* Generated from /home/lha/src/cvs/heimdal/lib/asn1/k5.asn1 */
+
+
+/* Generated from ./krb5.asn1 */
 /* Do not edit */
 
 #include <stdio.h>
@@ -2357,13 +3249,11 @@ copy_EncryptionKey(const EncryptionKey * from, EncryptionKey * to)
 #include <time.h>
 #include <string.h>
 #include <errno.h>
+#include <limits.h>
 #include <asn1_err.h>
 
-#define BACK if (e) return e; p -= l; len -= l; ret += l
-
 int
-encode_TicketFlags(unsigned char *p, size_t len, const TicketFlags * data,
-                  size_t * size)
+encode_TicketFlags(unsigned char *p, size_t len, const TicketFlags * data, size_t * size)
 {
     size_t ret = 0;
     size_t l;
@@ -2372,107 +3262,155 @@ encode_TicketFlags(unsigned char *p, size_t len, const TicketFlags * data,
     i = 0;
     {
        unsigned char c = 0;
+       if (len < 1)
+           return ASN1_OVERFLOW;
        *p-- = c;
        len--;
        ret++;
        c = 0;
+       if (len < 1)
+           return ASN1_OVERFLOW;
        *p-- = c;
        len--;
        ret++;
        c = 0;
-       if (data->anonymous)
+       if ((data)->anonymous) {
            c |= 1 << 1;
-       if (data->ok_as_delegate)
+       }
+       if ((data)->ok_as_delegate) {
            c |= 1 << 2;
-       if (data->transited_policy_checked)
+       }
+       if ((data)->transited_policy_checked) {
            c |= 1 << 3;
-       if (data->hw_authent)
+       }
+       if ((data)->hw_authent) {
            c |= 1 << 4;
-       if (data->pre_authent)
+       }
+       if ((data)->pre_authent) {
            c |= 1 << 5;
-       if (data->initial)
+       }
+       if ((data)->initial) {
            c |= 1 << 6;
-       if (data->renewable)
+       }
+       if ((data)->renewable) {
            c |= 1 << 7;
+       }
+       if (len < 1)
+           return ASN1_OVERFLOW;
        *p-- = c;
        len--;
        ret++;
        c = 0;
-       if (data->invalid)
+       if ((data)->invalid) {
            c |= 1 << 0;
-       if (data->postdated)
+       }
+       if ((data)->postdated) {
            c |= 1 << 1;
-       if (data->may_postdate)
+       }
+       if ((data)->may_postdate) {
            c |= 1 << 2;
-       if (data->proxy)
+       }
+       if ((data)->proxy) {
            c |= 1 << 3;
-       if (data->proxiable)
+       }
+       if ((data)->proxiable) {
            c |= 1 << 4;
-       if (data->forwarded)
+       }
+       if ((data)->forwarded) {
            c |= 1 << 5;
-       if (data->forwardable)
+       }
+       if ((data)->forwardable) {
            c |= 1 << 6;
-       if (data->reserved)
+       }
+       if ((data)->reserved) {
            c |= 1 << 7;
+       }
+       if (len < 1)
+           return ASN1_OVERFLOW;
        *p-- = c;
+       len--;
+       ret++;
+       if (len < 1)
+           return ASN1_OVERFLOW;
        *p-- = 0;
-       len -= 2;
-       ret += 2;
+       len -= 1;
+       ret += 1;
     }
 
-    e = der_put_length_and_tag(p, len, ret, UNIV, PRIM, UT_BitString, &l);
-    BACK;
+    e = der_put_length_and_tag(p, len, ret, ASN1_C_UNIV, PRIM, UT_BitString, &l);
+    if (e)
+       return e;
+    p -= l;
+    len -= l;
+    ret += l;
+
     *size = ret;
     return 0;
 }
 
-#define FORW if(e) goto fail; p += l; len -= l; ret += l
-
 int
-decode_TicketFlags(const unsigned char *p, size_t len, TicketFlags * data,
-                  size_t * size)
+decode_TicketFlags(const unsigned char *p, size_t len, TicketFlags * data, size_t * size)
 {
-    size_t ret = 0, reallen;
+    size_t ret = 0;
     size_t l;
     int e;
 
     memset(data, 0, sizeof(*data));
-    reallen = 0;
-    e = der_match_tag_and_length(p, len, UNIV, PRIM, UT_BitString, &reallen,
-                                &l);
-    FORW;
-    if (len < reallen)
-       return ASN1_OVERRUN;
-    p++;
-    len--;
-    reallen--;
-    ret++;
-    data->reserved = (*p >> 7) & 1;
-    data->forwardable = (*p >> 6) & 1;
-    data->forwarded = (*p >> 5) & 1;
-    data->proxiable = (*p >> 4) & 1;
-    data->proxy = (*p >> 3) & 1;
-    data->may_postdate = (*p >> 2) & 1;
-    data->postdated = (*p >> 1) & 1;
-    data->invalid = (*p >> 0) & 1;
-    p++;
-    len--;
-    reallen--;
-    ret++;
-    data->renewable = (*p >> 7) & 1;
-    data->initial = (*p >> 6) & 1;
-    data->pre_authent = (*p >> 5) & 1;
-    data->hw_authent = (*p >> 4) & 1;
-    data->transited_policy_checked = (*p >> 3) & 1;
-    data->ok_as_delegate = (*p >> 2) & 1;
-    data->anonymous = (*p >> 1) & 1;
-    p += reallen;
-    len -= reallen;
-    ret += reallen;
+    {
+       size_t Top_datalen, Top_oldlen;
+       Der_type Top_type;
+       e = der_match_tag_and_length(p, len, ASN1_C_UNIV, &Top_type, UT_BitString, &Top_datalen, &l);
+       if (e == 0 && Top_type != PRIM) {
+           e = ASN1_BAD_ID;
+       }
+       if (e)
+           goto fail;
+       p += l;
+       len -= l;
+       ret += l;
+       Top_oldlen = len;
+       if (Top_datalen > len) {
+           e = ASN1_OVERRUN;
+           goto fail;
+       }
+       len = Top_datalen;
+       if (len < 1)
+           return ASN1_OVERRUN;
+       p++;
+       len--;
+       ret++;
+       do {
+           if (len < 1)
+               break;
+           (data)->reserved = (*p >> 7) & 1;
+           (data)->forwardable = (*p >> 6) & 1;
+           (data)->forwarded = (*p >> 5) & 1;
+           (data)->proxiable = (*p >> 4) & 1;
+           (data)->proxy = (*p >> 3) & 1;
+           (data)->may_postdate = (*p >> 2) & 1;
+           (data)->postdated = (*p >> 1) & 1;
+           (data)->invalid = (*p >> 0) & 1;
+           p++;
+           len--;
+           ret++;
+           if (len < 1)
+               break;
+           (data)->renewable = (*p >> 7) & 1;
+           (data)->initial = (*p >> 6) & 1;
+           (data)->pre_authent = (*p >> 5) & 1;
+           (data)->hw_authent = (*p >> 4) & 1;
+           (data)->transited_policy_checked = (*p >> 3) & 1;
+           (data)->ok_as_delegate = (*p >> 2) & 1;
+           (data)->anonymous = (*p >> 1) & 1;
+       } while (0);
+       p += len;
+       ret += len;
+       len = Top_oldlen - Top_datalen;
+    }
     if (size)
        *size = ret;
     return 0;
-  fail:
+fail:
     free_TicketFlags(data);
     return e;
 }
@@ -2486,18 +3424,20 @@ size_t
 length_TicketFlags(const TicketFlags * data)
 {
     size_t ret = 0;
-    ret += 7;
+    ret += 5;
+    ret += 1 + der_length_len(ret);
     return ret;
 }
 
 int
 copy_TicketFlags(const TicketFlags * from, TicketFlags * to)
 {
+    memset(to, 0, sizeof(*to));
     *(to) = *(from);
     return 0;
 }
 
-unsigned
+unsigned 
 TicketFlags2int(TicketFlags f)
 {
     unsigned r = 0;
@@ -2534,11 +3474,13 @@ TicketFlags2int(TicketFlags f)
     return r;
 }
 
-TicketFlags
+TicketFlags 
 int2TicketFlags(unsigned n)
 {
     TicketFlags flags;
 
+    memset(&flags, 0, sizeof(flags));
+
     flags.reserved = (n >> 0) & 1;
     flags.forwardable = (n >> 1) & 1;
     flags.forwarded = (n >> 2) & 1;
@@ -2558,7 +3500,10 @@ int2TicketFlags(unsigned n)
 }
 
 
-/* Generated from /home/lha/src/cvs/heimdal/lib/asn1/k5.asn1 */
+
+
+
+/* Generated from ./krb5.asn1 */
 /* Do not edit */
 
 #include <stdio.h>
@@ -2566,10 +3511,9 @@ int2TicketFlags(unsigned n)
 #include <time.h>
 #include <string.h>
 #include <errno.h>
+#include <limits.h>
 #include <asn1_err.h>
 
-#define BACK if (e) return e; p -= l; len -= l; ret += l
-
 int
 encode_Realm(unsigned char *p, size_t len, const Realm * data, size_t * size)
 {
@@ -2578,29 +3522,62 @@ encode_Realm(unsigned char *p, size_t len, const Realm * data, size_t * size)
     int i, e;
 
     i = 0;
-    e = encode_general_string(p, len, data, &l);
-    BACK;
+    e = der_put_general_string(p, len, data, &l);
+    if (e)
+       return e;
+    p -= l;
+    len -= l;
+    ret += l;
+
+    e = der_put_length_and_tag(p, len, ret, ASN1_C_UNIV, PRIM, UT_GeneralString, &l);
+    if (e)
+       return e;
+    p -= l;
+    len -= l;
+    ret += l;
+
     *size = ret;
     return 0;
 }
 
-#define FORW if(e) goto fail; p += l; len -= l; ret += l
-
 int
 decode_Realm(const unsigned char *p, size_t len, Realm * data, size_t * size)
 {
-    size_t ret = 0, reallen;
+    size_t ret = 0;
     size_t l;
     int e;
 
     memset(data, 0, sizeof(*data));
-    reallen = 0;
-    e = decode_general_string(p, len, data, &l);
-    FORW;
+    {
+       size_t Top_datalen, Top_oldlen;
+       Der_type Top_type;
+       e = der_match_tag_and_length(p, len, ASN1_C_UNIV, &Top_type, UT_GeneralString, &Top_datalen, &l);
+       if (e == 0 && Top_type != PRIM) {
+           e = ASN1_BAD_ID;
+       }
+       if (e)
+           goto fail;
+       p += l;
+       len -= l;
+       ret += l;
+       Top_oldlen = len;
+       if (Top_datalen > len) {
+           e = ASN1_OVERRUN;
+           goto fail;
+       }
+       len = Top_datalen;
+       e = der_get_general_string(p, len, data, &l);
+       if (e)
+           goto fail;
+       p += l;
+       len -= l;
+       ret += l;
+       len = Top_oldlen - Top_datalen;
+    }
     if (size)
        *size = ret;
     return 0;
-  fail:
+fail:
     free_Realm(data);
     return e;
 }
@@ -2608,26 +3585,33 @@ decode_Realm(const unsigned char *p, size_t len, Realm * data, size_t * size)
 void
 free_Realm(Realm * data)
 {
-    free_general_string(data);
+    der_free_general_string(data);
 }
 
 size_t
 length_Realm(const Realm * data)
 {
     size_t ret = 0;
-    ret += length_general_string(data);
+    ret += der_length_general_string(data);
+    ret += 1 + der_length_len(ret);
     return ret;
 }
 
 int
 copy_Realm(const Realm * from, Realm * to)
 {
-    if (copy_general_string(from, to))
-       return ENOMEM;
+    memset(to, 0, sizeof(*to));
+    if (der_copy_general_string(from, to))
+       goto fail;
     return 0;
+fail:
+    free_Realm(to);
+    return ENOMEM;
 }
 
-/* Generated from /home/lha/src/cvs/heimdal/lib/asn1/k5.asn1 */
+
+
+/* Generated from ./krb5.asn1 */
 /* Do not edit */
 
 #include <stdio.h>
@@ -2635,43 +3619,81 @@ copy_Realm(const Realm * from, Realm * to)
 #include <time.h>
 #include <string.h>
 #include <errno.h>
+#include <limits.h>
 #include <asn1_err.h>
 
-#define BACK if (e) return e; p -= l; len -= l; ret += l
-
 int
-encode_ENCTYPE(unsigned char *p, size_t len, const ENCTYPE * data,
-              size_t * size)
+encode_ENCTYPE(unsigned char *p, size_t len, const ENCTYPE * data, size_t * size)
 {
     size_t ret = 0;
     size_t l;
     int i, e;
 
     i = 0;
-    e = encode_integer(p, len, (const int *)data, &l);
-    BACK;
+    {
+       int enumint = (int) *data;
+       e = der_put_integer(p, len, &enumint, &l);
+       if (e)
+           return e;
+       p -= l;
+       len -= l;
+       ret += l;
+
+    }
+    ;
+    e = der_put_length_and_tag(p, len, ret, ASN1_C_UNIV, PRIM, UT_Integer, &l);
+    if (e)
+       return e;
+    p -= l;
+    len -= l;
+    ret += l;
+
     *size = ret;
     return 0;
 }
 
-#define FORW if(e) goto fail; p += l; len -= l; ret += l
-
 int
-decode_ENCTYPE(const unsigned char *p, size_t len, ENCTYPE * data,
-              size_t * size)
+decode_ENCTYPE(const unsigned char *p, size_t len, ENCTYPE * data, size_t * size)
 {
-    size_t ret = 0, reallen;
+    size_t ret = 0;
     size_t l;
     int e;
 
     memset(data, 0, sizeof(*data));
-    reallen = 0;
-    e = decode_integer(p, len, (int *)data, &l);
-    FORW;
+    {
+       size_t Top_datalen, Top_oldlen;
+       Der_type Top_type;
+       e = der_match_tag_and_length(p, len, ASN1_C_UNIV, &Top_type, UT_Integer, &Top_datalen, &l);
+       if (e == 0 && Top_type != PRIM) {
+           e = ASN1_BAD_ID;
+       }
+       if (e)
+           goto fail;
+       p += l;
+       len -= l;
+       ret += l;
+       Top_oldlen = len;
+       if (Top_datalen > len) {
+           e = ASN1_OVERRUN;
+           goto fail;
+       }
+       len = Top_datalen;
+       {
+           int enumint;
+           e = der_get_integer(p, len, &enumint, &l);
+           if (e)
+               goto fail;
+           p += l;
+           len -= l;
+           ret += l;
+           *data = enumint;
+       }
+       len = Top_oldlen - Top_datalen;
+    }
     if (size)
        *size = ret;
     return 0;
-  fail:
+fail:
     free_ENCTYPE(data);
     return e;
 }
@@ -2685,18 +3707,25 @@ size_t
 length_ENCTYPE(const ENCTYPE * data)
 {
     size_t ret = 0;
-    ret += length_integer((const int *)data);
+    {
+       int enumint = *data;
+       ret += der_length_integer(&enumint);
+    }
+    ret += 1 + der_length_len(ret);
     return ret;
 }
 
 int
 copy_ENCTYPE(const ENCTYPE * from, ENCTYPE * to)
 {
+    memset(to, 0, sizeof(*to));
     *(to) = *(from);
     return 0;
 }
 
-/* Generated from /home/lha/src/cvs/heimdal/lib/asn1/k5.asn1 */
+
+
+/* Generated from ./krb5.asn1 */
 /* Do not edit */
 
 #include <stdio.h>
@@ -2704,43 +3733,81 @@ copy_ENCTYPE(const ENCTYPE * from, ENCTYPE * to)
 #include <time.h>
 #include <string.h>
 #include <errno.h>
+#include <limits.h>
 #include <asn1_err.h>
 
-#define BACK if (e) return e; p -= l; len -= l; ret += l
-
 int
-encode_NAME_TYPE(unsigned char *p, size_t len, const NAME_TYPE * data,
-                size_t * size)
+encode_NAME_TYPE(unsigned char *p, size_t len, const NAME_TYPE * data, size_t * size)
 {
     size_t ret = 0;
     size_t l;
     int i, e;
 
     i = 0;
-    e = encode_integer(p, len, (const int *)data, &l);
-    BACK;
+    {
+       int enumint = (int) *data;
+       e = der_put_integer(p, len, &enumint, &l);
+       if (e)
+           return e;
+       p -= l;
+       len -= l;
+       ret += l;
+
+    }
+    ;
+    e = der_put_length_and_tag(p, len, ret, ASN1_C_UNIV, PRIM, UT_Integer, &l);
+    if (e)
+       return e;
+    p -= l;
+    len -= l;
+    ret += l;
+
     *size = ret;
     return 0;
 }
 
-#define FORW if(e) goto fail; p += l; len -= l; ret += l
-
 int
-decode_NAME_TYPE(const unsigned char *p, size_t len, NAME_TYPE * data,
-                size_t * size)
+decode_NAME_TYPE(const unsigned char *p, size_t len, NAME_TYPE * data, size_t * size)
 {
-    size_t ret = 0, reallen;
+    size_t ret = 0;
     size_t l;
     int e;
 
     memset(data, 0, sizeof(*data));
-    reallen = 0;
-    e = decode_integer(p, len, (int *)data, &l);
-    FORW;
+    {
+       size_t Top_datalen, Top_oldlen;
+       Der_type Top_type;
+       e = der_match_tag_and_length(p, len, ASN1_C_UNIV, &Top_type, UT_Integer, &Top_datalen, &l);
+       if (e == 0 && Top_type != PRIM) {
+           e = ASN1_BAD_ID;
+       }
+       if (e)
+           goto fail;
+       p += l;
+       len -= l;
+       ret += l;
+       Top_oldlen = len;
+       if (Top_datalen > len) {
+           e = ASN1_OVERRUN;
+           goto fail;
+       }
+       len = Top_datalen;
+       {
+           int enumint;
+           e = der_get_integer(p, len, &enumint, &l);
+           if (e)
+               goto fail;
+           p += l;
+           len -= l;
+           ret += l;
+           *data = enumint;
+       }
+       len = Top_oldlen - Top_datalen;
+    }
     if (size)
        *size = ret;
     return 0;
-  fail:
+fail:
     free_NAME_TYPE(data);
     return e;
 }
@@ -2754,13 +3821,18 @@ size_t
 length_NAME_TYPE(const NAME_TYPE * data)
 {
     size_t ret = 0;
-    ret += length_integer((const int *)data);
+    {
+       int enumint = *data;
+       ret += der_length_integer(&enumint);
+    }
+    ret += 1 + der_length_len(ret);
     return ret;
 }
 
 int
 copy_NAME_TYPE(const NAME_TYPE * from, NAME_TYPE * to)
 {
+    memset(to, 0, sizeof(*to));
     *(to) = *(from);
     return 0;
 }
index 602dcdc..2d87f63 100644 (file)
@@ -1,4 +1,4 @@
-/* Generated from /home/lha/src/cvs/heimdal/lib/asn1/k5.asn1 */
+/* Generated from ./krb5.asn1 */
 /* Do not edit */
 
 #ifndef __krb5_asn1_h__
 #ifndef __asn1_common_definitions__
 #define __asn1_common_definitions__
 
-typedef struct octet_string {
-    size_t length;
-    void *data;
-} octet_string;
+typedef struct heim_integer {
+  size_t length;
+  void *data;
+  int negative;
+} heim_integer;
 
-typedef char *general_string;
+typedef struct heim_octet_string {
+  size_t length;
+  void *data;
+} heim_octet_string;
 
-typedef struct oid {
-    size_t length;
-    unsigned *components;
-} oid;
+typedef char *heim_general_string;
+
+typedef char *heim_utf8_string;
+
+typedef char *heim_printable_string;
+
+typedef char *heim_ia5_string;
+
+typedef struct heim_bmp_string {
+  size_t length;
+  uint16_t *data;
+} heim_bmp_string;
+
+typedef struct heim_universal_string {
+  size_t length;
+  uint32_t *data;
+} heim_universal_string;
+
+typedef char *heim_visible_string;
+
+typedef struct heim_oid {
+  size_t length;
+  unsigned *components;
+} heim_oid;
+
+typedef struct heim_bit_string {
+  size_t length;
+  void *data;
+} heim_bit_string;
+
+typedef struct heim_octet_string heim_any;
+typedef struct heim_octet_string heim_any_set;
 
 #define ASN1_MALLOC_ENCODE(T, B, BL, S, L, R)                  \
   do {                                                         \
@@ -38,242 +70,511 @@ typedef struct oid {
     }                                                          \
   } while (0)
 
+
 #endif
 
 /*
-NAME-TYPE ::= INTEGER
+NAME-TYPE ::= INTEGER {
+  KRB5_NT_UNKNOWN(0),
+  KRB5_NT_PRINCIPAL(1),
+  KRB5_NT_SRV_INST(2),
+  KRB5_NT_SRV_HST(3),
+  KRB5_NT_SRV_XHST(4),
+  KRB5_NT_UID(5),
+  KRB5_NT_X500_PRINCIPAL(6),
+  KRB5_NT_SMTP_NAME(7),
+  KRB5_NT_ENTERPRISE_PRINCIPAL(10),
+  KRB5_NT_WELLKNOWN(11),
+  KRB5_NT_ENT_PRINCIPAL_AND_ID(-130),
+  KRB5_NT_MS_PRINCIPAL(-128),
+  KRB5_NT_MS_PRINCIPAL_AND_ID(-129),
+  KRB5_NT_NTLM(-1200)
+}
 */
 
 typedef enum NAME_TYPE {
-    KRB5_NT_UNKNOWN = 0,
-    KRB5_NT_PRINCIPAL = 1,
-    KRB5_NT_SRV_INST = 2,
-    KRB5_NT_SRV_HST = 3,
-    KRB5_NT_SRV_XHST = 4,
-    KRB5_NT_UID = 5,
-    KRB5_NT_X500_PRINCIPAL = 6
+  KRB5_NT_UNKNOWN = 0,
+  KRB5_NT_PRINCIPAL = 1,
+  KRB5_NT_SRV_INST = 2,
+  KRB5_NT_SRV_HST = 3,
+  KRB5_NT_SRV_XHST = 4,
+  KRB5_NT_UID = 5,
+  KRB5_NT_X500_PRINCIPAL = 6,
+  KRB5_NT_SMTP_NAME = 7,
+  KRB5_NT_ENTERPRISE_PRINCIPAL = 10,
+  KRB5_NT_WELLKNOWN = 11,
+  KRB5_NT_ENT_PRINCIPAL_AND_ID = -130,
+  KRB5_NT_MS_PRINCIPAL = -128,
+  KRB5_NT_MS_PRINCIPAL_AND_ID = -129,
+  KRB5_NT_NTLM = -1200
 } NAME_TYPE;
 
-int encode_NAME_TYPE(unsigned char *, size_t, const NAME_TYPE *, size_t *);
-int decode_NAME_TYPE(const unsigned char *, size_t, NAME_TYPE *, size_t *);
-void free_NAME_TYPE(NAME_TYPE *);
+int    decode_NAME_TYPE(const unsigned char *, size_t, NAME_TYPE *, size_t *);
+int    encode_NAME_TYPE(unsigned char *, size_t, const NAME_TYPE *, size_t *);
 size_t length_NAME_TYPE(const NAME_TYPE *);
-int copy_NAME_TYPE(const NAME_TYPE *, NAME_TYPE *);
+int    copy_NAME_TYPE  (const NAME_TYPE *, NAME_TYPE *);
+void   free_NAME_TYPE  (NAME_TYPE *);
 
 
 /*
-MESSAGE-TYPE ::= INTEGER
+MESSAGE-TYPE ::= INTEGER {
+  krb_as_req(10),
+  krb_as_rep(11),
+  krb_tgs_req(12),
+  krb_tgs_rep(13),
+  krb_ap_req(14),
+  krb_ap_rep(15),
+  krb_safe(20),
+  krb_priv(21),
+  krb_cred(22),
+  krb_error(30)
+}
 */
 
 typedef enum MESSAGE_TYPE {
-    krb_as_req = 10,
-    krb_as_rep = 11,
-    krb_tgs_req = 12,
-    krb_tgs_rep = 13,
-    krb_ap_req = 14,
-    krb_ap_rep = 15,
-    krb_safe = 20,
-    krb_priv = 21,
-    krb_cred = 22,
-    krb_error = 30
+  krb_as_req = 10,
+  krb_as_rep = 11,
+  krb_tgs_req = 12,
+  krb_tgs_rep = 13,
+  krb_ap_req = 14,
+  krb_ap_rep = 15,
+  krb_safe = 20,
+  krb_priv = 21,
+  krb_cred = 22,
+  krb_error = 30
 } MESSAGE_TYPE;
 
-int encode_MESSAGE_TYPE(unsigned char *, size_t, const MESSAGE_TYPE *,
-                       size_t *);
-int decode_MESSAGE_TYPE(const unsigned char *, size_t, MESSAGE_TYPE *,
-                       size_t *);
-void free_MESSAGE_TYPE(MESSAGE_TYPE *);
+int    decode_MESSAGE_TYPE(const unsigned char *, size_t, MESSAGE_TYPE *, size_t *);
+int    encode_MESSAGE_TYPE(unsigned char *, size_t, const MESSAGE_TYPE *, size_t *);
 size_t length_MESSAGE_TYPE(const MESSAGE_TYPE *);
-int copy_MESSAGE_TYPE(const MESSAGE_TYPE *, MESSAGE_TYPE *);
+int    copy_MESSAGE_TYPE  (const MESSAGE_TYPE *, MESSAGE_TYPE *);
+void   free_MESSAGE_TYPE  (MESSAGE_TYPE *);
 
 
 /*
-PADATA-TYPE ::= INTEGER
+PADATA-TYPE ::= INTEGER {
+  KRB5_PADATA_NONE(0),
+  KRB5_PADATA_TGS_REQ(1),
+  KRB5_PADATA_AP_REQ(1),
+  KRB5_PADATA_ENC_TIMESTAMP(2),
+  KRB5_PADATA_PW_SALT(3),
+  KRB5_PADATA_ENC_UNIX_TIME(5),
+  KRB5_PADATA_SANDIA_SECUREID(6),
+  KRB5_PADATA_SESAME(7),
+  KRB5_PADATA_OSF_DCE(8),
+  KRB5_PADATA_CYBERSAFE_SECUREID(9),
+  KRB5_PADATA_AFS3_SALT(10),
+  KRB5_PADATA_ETYPE_INFO(11),
+  KRB5_PADATA_SAM_CHALLENGE(12),
+  KRB5_PADATA_SAM_RESPONSE(13),
+  KRB5_PADATA_PK_AS_REQ_19(14),
+  KRB5_PADATA_PK_AS_REP_19(15),
+  KRB5_PADATA_PK_AS_REQ_WIN(15),
+  KRB5_PADATA_PK_AS_REQ(16),
+  KRB5_PADATA_PK_AS_REP(17),
+  KRB5_PADATA_PA_PK_OCSP_RESPONSE(18),
+  KRB5_PADATA_ETYPE_INFO2(19),
+  KRB5_PADATA_USE_SPECIFIED_KVNO(20),
+  KRB5_PADATA_SVR_REFERRAL_INFO(20),
+  KRB5_PADATA_SAM_REDIRECT(21),
+  KRB5_PADATA_GET_FROM_TYPED_DATA(22),
+  KRB5_PADATA_SAM_ETYPE_INFO(23),
+  KRB5_PADATA_SERVER_REFERRAL(25),
+  KRB5_PADATA_ALT_PRINC(24),
+  KRB5_PADATA_SAM_CHALLENGE2(30),
+  KRB5_PADATA_SAM_RESPONSE2(31),
+  KRB5_PA_EXTRA_TGT(41),
+  KRB5_PADATA_TD_KRB_PRINCIPAL(102),
+  KRB5_PADATA_PK_TD_TRUSTED_CERTIFIERS(104),
+  KRB5_PADATA_PK_TD_CERTIFICATE_INDEX(105),
+  KRB5_PADATA_TD_APP_DEFINED_ERROR(106),
+  KRB5_PADATA_TD_REQ_NONCE(107),
+  KRB5_PADATA_TD_REQ_SEQ(108),
+  KRB5_PADATA_PA_PAC_REQUEST(128),
+  KRB5_PADATA_FOR_USER(129),
+  KRB5_PADATA_FOR_X509_USER(130),
+  KRB5_PADATA_FOR_CHECK_DUPS(131),
+  KRB5_PADATA_AS_CHECKSUM(132),
+  KRB5_PADATA_PK_AS_09_BINDING(132),
+  KRB5_PADATA_CLIENT_CANONICALIZED(133),
+  KRB5_PADATA_FX_COOKIE(133),
+  KRB5_PADATA_AUTHENTICATION_SET(134),
+  KRB5_PADATA_AUTH_SET_SELECTED(135),
+  KRB5_PADATA_FX_FAST(136),
+  KRB5_PADATA_FX_ERROR(137),
+  KRB5_PADATA_ENCRYPTED_CHALLENGE(138),
+  KRB5_PADATA_OTP_CHALLENGE(141),
+  KRB5_PADATA_OTP_REQUEST(142),
+  KBB5_PADATA_OTP_CONFIRM(143),
+  KRB5_PADATA_OTP_PIN_CHANGE(144),
+  KRB5_PADATA_EPAK_AS_REQ(145),
+  KRB5_PADATA_EPAK_AS_REP(146),
+  KRB5_PADATA_PKINIT_KX(147),
+  KRB5_PADATA_PKU2U_NAME(148),
+  KRB5_PADATA_SUPPORTED_ETYPES(165)
+}
 */
 
 typedef enum PADATA_TYPE {
-    KRB5_PADATA_NONE = 0,
-    KRB5_PADATA_TGS_REQ = 1,
-    KRB5_PADATA_AP_REQ = 1,
-    KRB5_PADATA_ENC_TIMESTAMP = 2,
-    KRB5_PADATA_PW_SALT = 3,
-    KRB5_PADATA_ENC_UNIX_TIME = 5,
-    KRB5_PADATA_SANDIA_SECUREID = 6,
-    KRB5_PADATA_SESAME = 7,
-    KRB5_PADATA_OSF_DCE = 8,
-    KRB5_PADATA_CYBERSAFE_SECUREID = 9,
-    KRB5_PADATA_AFS3_SALT = 10,
-    KRB5_PADATA_ETYPE_INFO = 11,
-    KRB5_PADATA_SAM_CHALLENGE = 12,
-    KRB5_PADATA_SAM_RESPONSE = 13,
-    KRB5_PADATA_PK_AS_REQ = 14,
-    KRB5_PADATA_PK_AS_REP = 15,
-    KRB5_PADATA_PK_AS_SIGN = 16,
-    KRB5_PADATA_PK_KEY_REQ = 17,
-    KRB5_PADATA_PK_KEY_REP = 18,
-    KRB5_PADATA_USE_SPECIFIED_KVNO = 20,
-    KRB5_PADATA_SAM_REDIRECT = 21,
-    KRB5_PADATA_GET_FROM_TYPED_DATA = 22,
-    KRB5_PADATA_SAM_ETYPE_INFO = 23
+  KRB5_PADATA_NONE = 0,
+  KRB5_PADATA_TGS_REQ = 1,
+  KRB5_PADATA_AP_REQ = 1,
+  KRB5_PADATA_ENC_TIMESTAMP = 2,
+  KRB5_PADATA_PW_SALT = 3,
+  KRB5_PADATA_ENC_UNIX_TIME = 5,
+  KRB5_PADATA_SANDIA_SECUREID = 6,
+  KRB5_PADATA_SESAME = 7,
+  KRB5_PADATA_OSF_DCE = 8,
+  KRB5_PADATA_CYBERSAFE_SECUREID = 9,
+  KRB5_PADATA_AFS3_SALT = 10,
+  KRB5_PADATA_ETYPE_INFO = 11,
+  KRB5_PADATA_SAM_CHALLENGE = 12,
+  KRB5_PADATA_SAM_RESPONSE = 13,
+  KRB5_PADATA_PK_AS_REQ_19 = 14,
+  KRB5_PADATA_PK_AS_REP_19 = 15,
+  KRB5_PADATA_PK_AS_REQ_WIN = 15,
+  KRB5_PADATA_PK_AS_REQ = 16,
+  KRB5_PADATA_PK_AS_REP = 17,
+  KRB5_PADATA_PA_PK_OCSP_RESPONSE = 18,
+  KRB5_PADATA_ETYPE_INFO2 = 19,
+  KRB5_PADATA_USE_SPECIFIED_KVNO = 20,
+  KRB5_PADATA_SVR_REFERRAL_INFO = 20,
+  KRB5_PADATA_SAM_REDIRECT = 21,
+  KRB5_PADATA_GET_FROM_TYPED_DATA = 22,
+  KRB5_PADATA_SAM_ETYPE_INFO = 23,
+  KRB5_PADATA_SERVER_REFERRAL = 25,
+  KRB5_PADATA_ALT_PRINC = 24,
+  KRB5_PADATA_SAM_CHALLENGE2 = 30,
+  KRB5_PADATA_SAM_RESPONSE2 = 31,
+  KRB5_PA_EXTRA_TGT = 41,
+  KRB5_PADATA_TD_KRB_PRINCIPAL = 102,
+  KRB5_PADATA_PK_TD_TRUSTED_CERTIFIERS = 104,
+  KRB5_PADATA_PK_TD_CERTIFICATE_INDEX = 105,
+  KRB5_PADATA_TD_APP_DEFINED_ERROR = 106,
+  KRB5_PADATA_TD_REQ_NONCE = 107,
+  KRB5_PADATA_TD_REQ_SEQ = 108,
+  KRB5_PADATA_PA_PAC_REQUEST = 128,
+  KRB5_PADATA_FOR_USER = 129,
+  KRB5_PADATA_FOR_X509_USER = 130,
+  KRB5_PADATA_FOR_CHECK_DUPS = 131,
+  KRB5_PADATA_AS_CHECKSUM = 132,
+  KRB5_PADATA_PK_AS_09_BINDING = 132,
+  KRB5_PADATA_CLIENT_CANONICALIZED = 133,
+  KRB5_PADATA_FX_COOKIE = 133,
+  KRB5_PADATA_AUTHENTICATION_SET = 134,
+  KRB5_PADATA_AUTH_SET_SELECTED = 135,
+  KRB5_PADATA_FX_FAST = 136,
+  KRB5_PADATA_FX_ERROR = 137,
+  KRB5_PADATA_ENCRYPTED_CHALLENGE = 138,
+  KRB5_PADATA_OTP_CHALLENGE = 141,
+  KRB5_PADATA_OTP_REQUEST = 142,
+  KBB5_PADATA_OTP_CONFIRM = 143,
+  KRB5_PADATA_OTP_PIN_CHANGE = 144,
+  KRB5_PADATA_EPAK_AS_REQ = 145,
+  KRB5_PADATA_EPAK_AS_REP = 146,
+  KRB5_PADATA_PKINIT_KX = 147,
+  KRB5_PADATA_PKU2U_NAME = 148,
+  KRB5_PADATA_SUPPORTED_ETYPES = 165
 } PADATA_TYPE;
 
-int encode_PADATA_TYPE(unsigned char *, size_t, const PADATA_TYPE *,
-                      size_t *);
-int decode_PADATA_TYPE(const unsigned char *, size_t, PADATA_TYPE *,
-                      size_t *);
-void free_PADATA_TYPE(PADATA_TYPE *);
+int    decode_PADATA_TYPE(const unsigned char *, size_t, PADATA_TYPE *, size_t *);
+int    encode_PADATA_TYPE(unsigned char *, size_t, const PADATA_TYPE *, size_t *);
 size_t length_PADATA_TYPE(const PADATA_TYPE *);
-int copy_PADATA_TYPE(const PADATA_TYPE *, PADATA_TYPE *);
+int    copy_PADATA_TYPE  (const PADATA_TYPE *, PADATA_TYPE *);
+void   free_PADATA_TYPE  (PADATA_TYPE *);
+
+
+/*
+AUTHDATA-TYPE ::= INTEGER {
+  KRB5_AUTHDATA_IF_RELEVANT(1),
+  KRB5_AUTHDATA_INTENDED_FOR_SERVER(2),
+  KRB5_AUTHDATA_INTENDED_FOR_APPLICATION_CLASS(3),
+  KRB5_AUTHDATA_KDC_ISSUED(4),
+  KRB5_AUTHDATA_AND_OR(5),
+  KRB5_AUTHDATA_MANDATORY_TICKET_EXTENSIONS(6),
+  KRB5_AUTHDATA_IN_TICKET_EXTENSIONS(7),
+  KRB5_AUTHDATA_MANDATORY_FOR_KDC(8),
+  KRB5_AUTHDATA_INITIAL_VERIFIED_CAS(9),
+  KRB5_AUTHDATA_OSF_DCE(64),
+  KRB5_AUTHDATA_SESAME(65),
+  KRB5_AUTHDATA_OSF_DCE_PKI_CERTID(66),
+  KRB5_AUTHDATA_WIN2K_PAC(128),
+  KRB5_AUTHDATA_GSS_API_ETYPE_NEGOTIATION(129),
+  KRB5_AUTHDATA_SIGNTICKET_OLDER(-17),
+  KRB5_AUTHDATA_SIGNTICKET_OLD(142),
+  KRB5_AUTHDATA_SIGNTICKET(512)
+}
+*/
+
+typedef enum AUTHDATA_TYPE {
+  KRB5_AUTHDATA_IF_RELEVANT = 1,
+  KRB5_AUTHDATA_INTENDED_FOR_SERVER = 2,
+  KRB5_AUTHDATA_INTENDED_FOR_APPLICATION_CLASS = 3,
+  KRB5_AUTHDATA_KDC_ISSUED = 4,
+  KRB5_AUTHDATA_AND_OR = 5,
+  KRB5_AUTHDATA_MANDATORY_TICKET_EXTENSIONS = 6,
+  KRB5_AUTHDATA_IN_TICKET_EXTENSIONS = 7,
+  KRB5_AUTHDATA_MANDATORY_FOR_KDC = 8,
+  KRB5_AUTHDATA_INITIAL_VERIFIED_CAS = 9,
+  KRB5_AUTHDATA_OSF_DCE = 64,
+  KRB5_AUTHDATA_SESAME = 65,
+  KRB5_AUTHDATA_OSF_DCE_PKI_CERTID = 66,
+  KRB5_AUTHDATA_WIN2K_PAC = 128,
+  KRB5_AUTHDATA_GSS_API_ETYPE_NEGOTIATION = 129,
+  KRB5_AUTHDATA_SIGNTICKET_OLDER = -17,
+  KRB5_AUTHDATA_SIGNTICKET_OLD = 142,
+  KRB5_AUTHDATA_SIGNTICKET = 512
+} AUTHDATA_TYPE;
+
+int    decode_AUTHDATA_TYPE(const unsigned char *, size_t, AUTHDATA_TYPE *, size_t *);
+int    encode_AUTHDATA_TYPE(unsigned char *, size_t, const AUTHDATA_TYPE *, size_t *);
+size_t length_AUTHDATA_TYPE(const AUTHDATA_TYPE *);
+int    copy_AUTHDATA_TYPE  (const AUTHDATA_TYPE *, AUTHDATA_TYPE *);
+void   free_AUTHDATA_TYPE  (AUTHDATA_TYPE *);
 
 
 /*
-CKSUMTYPE ::= INTEGER
+CKSUMTYPE ::= INTEGER {
+  CKSUMTYPE_NONE(0),
+  CKSUMTYPE_CRC32(1),
+  CKSUMTYPE_RSA_MD4(2),
+  CKSUMTYPE_RSA_MD4_DES(3),
+  CKSUMTYPE_DES_MAC(4),
+  CKSUMTYPE_DES_MAC_K(5),
+  CKSUMTYPE_RSA_MD4_DES_K(6),
+  CKSUMTYPE_RSA_MD5(7),
+  CKSUMTYPE_RSA_MD5_DES(8),
+  CKSUMTYPE_RSA_MD5_DES3(9),
+  CKSUMTYPE_SHA1_OTHER(10),
+  CKSUMTYPE_HMAC_SHA1_DES3(12),
+  CKSUMTYPE_SHA1(14),
+  CKSUMTYPE_HMAC_SHA1_96_AES_128(15),
+  CKSUMTYPE_HMAC_SHA1_96_AES_256(16),
+  CKSUMTYPE_GSSAPI(32771),
+  CKSUMTYPE_HMAC_MD5(-138),
+  CKSUMTYPE_HMAC_MD5_ENC(-1138)
+}
 */
 
 typedef enum CKSUMTYPE {
-    CKSUMTYPE_NONE = 0,
-    CKSUMTYPE_CRC32 = 1,
-    CKSUMTYPE_RSA_MD4 = 2,
-    CKSUMTYPE_RSA_MD4_DES = 3,
-    CKSUMTYPE_DES_MAC = 4,
-    CKSUMTYPE_DES_MAC_K = 5,
-    CKSUMTYPE_RSA_MD4_DES_K = 6,
-    CKSUMTYPE_RSA_MD5 = 7,
-    CKSUMTYPE_RSA_MD5_DES = 8,
-    CKSUMTYPE_RSA_MD5_DES3 = 9,
-    CKSUMTYPE_HMAC_SHA1_DES3 = 12,
-    CKSUMTYPE_SHA1 = 1000,
-    CKSUMTYPE_GSSAPI = 32771,
-    CKSUMTYPE_HMAC_MD5 = -138,
-    CKSUMTYPE_HMAC_MD5_ENC = -1138
+  CKSUMTYPE_NONE = 0,
+  CKSUMTYPE_CRC32 = 1,
+  CKSUMTYPE_RSA_MD4 = 2,
+  CKSUMTYPE_RSA_MD4_DES = 3,
+  CKSUMTYPE_DES_MAC = 4,
+  CKSUMTYPE_DES_MAC_K = 5,
+  CKSUMTYPE_RSA_MD4_DES_K = 6,
+  CKSUMTYPE_RSA_MD5 = 7,
+  CKSUMTYPE_RSA_MD5_DES = 8,
+  CKSUMTYPE_RSA_MD5_DES3 = 9,
+  CKSUMTYPE_SHA1_OTHER = 10,
+  CKSUMTYPE_HMAC_SHA1_DES3 = 12,
+  CKSUMTYPE_SHA1 = 14,
+  CKSUMTYPE_HMAC_SHA1_96_AES_128 = 15,
+  CKSUMTYPE_HMAC_SHA1_96_AES_256 = 16,
+  CKSUMTYPE_GSSAPI = 32771,
+  CKSUMTYPE_HMAC_MD5 = -138,
+  CKSUMTYPE_HMAC_MD5_ENC = -1138
 } CKSUMTYPE;
 
-int encode_CKSUMTYPE(unsigned char *, size_t, const CKSUMTYPE *, size_t *);
-int decode_CKSUMTYPE(const unsigned char *, size_t, CKSUMTYPE *, size_t *);
-void free_CKSUMTYPE(CKSUMTYPE *);
+int    decode_CKSUMTYPE(const unsigned char *, size_t, CKSUMTYPE *, size_t *);
+int    encode_CKSUMTYPE(unsigned char *, size_t, const CKSUMTYPE *, size_t *);
 size_t length_CKSUMTYPE(const CKSUMTYPE *);
-int copy_CKSUMTYPE(const CKSUMTYPE *, CKSUMTYPE *);
+int    copy_CKSUMTYPE  (const CKSUMTYPE *, CKSUMTYPE *);
+void   free_CKSUMTYPE  (CKSUMTYPE *);
 
 
 /*
-ENCTYPE ::= INTEGER
+ENCTYPE ::= INTEGER {
+  ETYPE_NULL(0),
+  ETYPE_DES_CBC_CRC(1),
+  ETYPE_DES_CBC_MD4(2),
+  ETYPE_DES_CBC_MD5(3),
+  ETYPE_DES3_CBC_MD5(5),
+  ETYPE_OLD_DES3_CBC_SHA1(7),
+  ETYPE_SIGN_DSA_GENERATE(8),
+  ETYPE_ENCRYPT_RSA_PRIV(9),
+  ETYPE_ENCRYPT_RSA_PUB(10),
+  ETYPE_DES3_CBC_SHA1(16),
+  ETYPE_AES128_CTS_HMAC_SHA1_96(17),
+  ETYPE_AES256_CTS_HMAC_SHA1_96(18),
+  ETYPE_ARCFOUR_HMAC_MD5(23),
+  ETYPE_ARCFOUR_HMAC_MD5_56(24),
+  ETYPE_ENCTYPE_PK_CROSS(48),
+  ETYPE_ARCFOUR_MD4(-128),
+  ETYPE_ARCFOUR_HMAC_OLD(-133),
+  ETYPE_ARCFOUR_HMAC_OLD_EXP(-135),
+  ETYPE_DES_CBC_NONE(-4096),
+  ETYPE_DES3_CBC_NONE(-4097),
+  ETYPE_DES_CFB64_NONE(-4098),
+  ETYPE_DES_PCBC_NONE(-4099),
+  ETYPE_DIGEST_MD5_NONE(-4100),
+  ETYPE_CRAM_MD5_NONE(-4101)
+}
 */
 
 typedef enum ENCTYPE {
-    ETYPE_NULL = 0,
-    ETYPE_DES_CBC_CRC = 1,
-    ETYPE_DES_CBC_MD4 = 2,
-    ETYPE_DES_CBC_MD5 = 3,
-    ETYPE_DES3_CBC_MD5 = 5,
-    ETYPE_OLD_DES3_CBC_SHA1 = 7,
-    ETYPE_SIGN_DSA_GENERATE = 8,
-    ETYPE_ENCRYPT_RSA_PRIV = 9,
-    ETYPE_ENCRYPT_RSA_PUB = 10,
-    ETYPE_DES3_CBC_SHA1 = 16,
-    ETYPE_ARCFOUR_HMAC_MD5 = 23,
-    ETYPE_ARCFOUR_HMAC_MD5_56 = 24,
-    ETYPE_ENCTYPE_PK_CROSS = 48,
-    ETYPE_DES_CBC_NONE = -4096,
-    ETYPE_DES3_CBC_NONE = -4097,
-    ETYPE_DES_CFB64_NONE = -4098,
-    ETYPE_DES_PCBC_NONE = -4099
+  ETYPE_NULL = 0,
+  ETYPE_DES_CBC_CRC = 1,
+  ETYPE_DES_CBC_MD4 = 2,
+  ETYPE_DES_CBC_MD5 = 3,
+  ETYPE_DES3_CBC_MD5 = 5,
+  ETYPE_OLD_DES3_CBC_SHA1 = 7,
+  ETYPE_SIGN_DSA_GENERATE = 8,
+  ETYPE_ENCRYPT_RSA_PRIV = 9,
+  ETYPE_ENCRYPT_RSA_PUB = 10,
+  ETYPE_DES3_CBC_SHA1 = 16,
+  ETYPE_AES128_CTS_HMAC_SHA1_96 = 17,
+  ETYPE_AES256_CTS_HMAC_SHA1_96 = 18,
+  ETYPE_ARCFOUR_HMAC_MD5 = 23,
+  ETYPE_ARCFOUR_HMAC_MD5_56 = 24,
+  ETYPE_ENCTYPE_PK_CROSS = 48,
+  ETYPE_ARCFOUR_MD4 = -128,
+  ETYPE_ARCFOUR_HMAC_OLD = -133,
+  ETYPE_ARCFOUR_HMAC_OLD_EXP = -135,
+  ETYPE_DES_CBC_NONE = -4096,
+  ETYPE_DES3_CBC_NONE = -4097,
+  ETYPE_DES_CFB64_NONE = -4098,
+  ETYPE_DES_PCBC_NONE = -4099,
+  ETYPE_DIGEST_MD5_NONE = -4100,
+  ETYPE_CRAM_MD5_NONE = -4101
 } ENCTYPE;
 
-int encode_ENCTYPE(unsigned char *, size_t, const ENCTYPE *, size_t *);
-int decode_ENCTYPE(const unsigned char *, size_t, ENCTYPE *, size_t *);
-void free_ENCTYPE(ENCTYPE *);
+int    decode_ENCTYPE(const unsigned char *, size_t, ENCTYPE *, size_t *);
+int    encode_ENCTYPE(unsigned char *, size_t, const ENCTYPE *, size_t *);
 size_t length_ENCTYPE(const ENCTYPE *);
-int copy_ENCTYPE(const ENCTYPE *, ENCTYPE *);
+int    copy_ENCTYPE  (const ENCTYPE *, ENCTYPE *);
+void   free_ENCTYPE  (ENCTYPE *);
 
 
 /*
-UNSIGNED ::= UNSIGNED INTEGER
+krb5uint32 ::= INTEGER (0..-1)
 */
 
-typedef unsigned int UNSIGNED;
+typedef unsigned int krb5uint32;
 
-int encode_UNSIGNED(unsigned char *, size_t, const UNSIGNED *, size_t *);
-int decode_UNSIGNED(const unsigned char *, size_t, UNSIGNED *, size_t *);
-void free_UNSIGNED(UNSIGNED *);
-size_t length_UNSIGNED(const UNSIGNED *);
-int copy_UNSIGNED(const UNSIGNED *, UNSIGNED *);
+int    decode_krb5uint32(const unsigned char *, size_t, krb5uint32 *, size_t *);
+int    encode_krb5uint32(unsigned char *, size_t, const krb5uint32 *, size_t *);
+size_t length_krb5uint32(const krb5uint32 *);
+int    copy_krb5uint32  (const krb5uint32 *, krb5uint32 *);
+void   free_krb5uint32  (krb5uint32 *);
+
+
+/*
+krb5int32 ::= INTEGER (-2147483648..2147483647)
+*/
+
+typedef int krb5int32;
+
+int    decode_krb5int32(const unsigned char *, size_t, krb5int32 *, size_t *);
+int    encode_krb5int32(unsigned char *, size_t, const krb5int32 *, size_t *);
+size_t length_krb5int32(const krb5int32 *);
+int    copy_krb5int32  (const krb5int32 *, krb5int32 *);
+void   free_krb5int32  (krb5int32 *);
+
+
+/*
+KerberosString ::= GeneralString
+*/
+
+typedef heim_general_string KerberosString;
+
+int    decode_KerberosString(const unsigned char *, size_t, KerberosString *, size_t *);
+int    encode_KerberosString(unsigned char *, size_t, const KerberosString *, size_t *);
+size_t length_KerberosString(const KerberosString *);
+int    copy_KerberosString  (const KerberosString *, KerberosString *);
+void   free_KerberosString  (KerberosString *);
 
 
 /*
 Realm ::= GeneralString
 */
 
-typedef general_string Realm;
+typedef heim_general_string Realm;
 
-int encode_Realm(unsigned char *, size_t, const Realm *, size_t *);
-int decode_Realm(const unsigned char *, size_t, Realm *, size_t *);
-void free_Realm(Realm *);
+int    decode_Realm(const unsigned char *, size_t, Realm *, size_t *);
+int    encode_Realm(unsigned char *, size_t, const Realm *, size_t *);
 size_t length_Realm(const Realm *);
-int copy_Realm(const Realm *, Realm *);
+int    copy_Realm  (const Realm *, Realm *);
+void   free_Realm  (Realm *);
 
 
 /*
 PrincipalName ::= SEQUENCE {
-  name-type[0]    NAME-TYPE,
-  name-string[1]  SEQUENCE OF GeneralString
+  name-type       [0] NAME-TYPE,
+  name-string     [1] SEQUENCE OF GeneralString,
 }
 */
 
 typedef struct PrincipalName {
-    NAME_TYPE name_type;
-    struct {
-       unsigned int len;
-       general_string *val;
-    } name_string;
+  NAME_TYPE name_type;
+  struct PrincipalName_name_string {
+    unsigned int len;
+    heim_general_string *val;
+  } name_string;
 } PrincipalName;
 
-int encode_PrincipalName(unsigned char *, size_t, const PrincipalName *,
-                        size_t *);
-int decode_PrincipalName(const unsigned char *, size_t, PrincipalName *,
-                        size_t *);
-void free_PrincipalName(PrincipalName *);
+int    decode_PrincipalName(const unsigned char *, size_t, PrincipalName *, size_t *);
+int    encode_PrincipalName(unsigned char *, size_t, const PrincipalName *, size_t *);
 size_t length_PrincipalName(const PrincipalName *);
-int copy_PrincipalName(const PrincipalName *, PrincipalName *);
+int    copy_PrincipalName  (const PrincipalName *, PrincipalName *);
+void   free_PrincipalName  (PrincipalName *);
 
 
 /*
 Principal ::= SEQUENCE {
-  name[0]         PrincipalName,
-  realm[1]        Realm
+  name            [0] PrincipalName,
+  realm           [1] Realm,
 }
 */
 
 typedef struct Principal {
-    PrincipalName name;
-    Realm realm;
+  PrincipalName name;
+  Realm realm;
 } Principal;
 
-int encode_Principal(unsigned char *, size_t, const Principal *, size_t *);
-int decode_Principal(const unsigned char *, size_t, Principal *, size_t *);
-void free_Principal(Principal *);
+int    decode_Principal(const unsigned char *, size_t, Principal *, size_t *);
+int    encode_Principal(unsigned char *, size_t, const Principal *, size_t *);
 size_t length_Principal(const Principal *);
-int copy_Principal(const Principal *, Principal *);
+int    copy_Principal  (const Principal *, Principal *);
+void   free_Principal  (Principal *);
+
+
+/*
+Principals ::= SEQUENCE OF Principal
+*/
+
+typedef struct Principals {
+  unsigned int len;
+  Principal *val;
+} Principals;
+
+int   add_Principals  (Principals *, const Principal *);
+int   remove_Principals  (Principals *, unsigned int);
+int    decode_Principals(const unsigned char *, size_t, Principals *, size_t *);
+int    encode_Principals(unsigned char *, size_t, const Principals *, size_t *);
+size_t length_Principals(const Principals *);
+int    copy_Principals  (const Principals *, Principals *);
+void   free_Principals  (Principals *);
 
 
 /*
 HostAddress ::= SEQUENCE {
-  addr-type[0]    INTEGER,
-  address[1]      OCTET STRING
+  addr-type       [0] krb5int32,
+  address         [1] OCTET STRING,
 }
 */
 
 typedef struct HostAddress {
-    int addr_type;
-    octet_string address;
+  krb5int32 addr_type;
+  heim_octet_string address;
 } HostAddress;
 
-int encode_HostAddress(unsigned char *, size_t, const HostAddress *,
-                      size_t *);
-int decode_HostAddress(const unsigned char *, size_t, HostAddress *,
-                      size_t *);
-void free_HostAddress(HostAddress *);
+int    decode_HostAddress(const unsigned char *, size_t, HostAddress *, size_t *);
+int    encode_HostAddress(unsigned char *, size_t, const HostAddress *, size_t *);
 size_t length_HostAddress(const HostAddress *);
-int copy_HostAddress(const HostAddress *, HostAddress *);
+int    copy_HostAddress  (const HostAddress *, HostAddress *);
+void   free_HostAddress  (HostAddress *);
 
 
 /*
@@ -281,17 +582,15 @@ HostAddresses ::= SEQUENCE OF HostAddress
 */
 
 typedef struct HostAddresses {
-    unsigned int len;
-    HostAddress *val;
+  unsigned int len;
+  HostAddress *val;
 } HostAddresses;
 
-int encode_HostAddresses(unsigned char *, size_t, const HostAddresses *,
-                        size_t *);
-int decode_HostAddresses(const unsigned char *, size_t, HostAddresses *,
-                        size_t *);
-void free_HostAddresses(HostAddresses *);
+int    decode_HostAddresses(const unsigned char *, size_t, HostAddresses *, size_t *);
+int    encode_HostAddresses(unsigned char *, size_t, const HostAddresses *, size_t *);
 size_t length_HostAddresses(const HostAddresses *);
-int copy_HostAddresses(const HostAddresses *, HostAddresses *);
+int    copy_HostAddresses  (const HostAddresses *, HostAddresses *);
+void   free_HostAddresses  (HostAddresses *);
 
 
 /*
@@ -300,37 +599,48 @@ KerberosTime ::= GeneralizedTime
 
 typedef time_t KerberosTime;
 
-int encode_KerberosTime(unsigned char *, size_t, const KerberosTime *,
-                       size_t *);
-int decode_KerberosTime(const unsigned char *, size_t, KerberosTime *,
-                       size_t *);
-void free_KerberosTime(KerberosTime *);
+int    decode_KerberosTime(const unsigned char *, size_t, KerberosTime *, size_t *);
+int    encode_KerberosTime(unsigned char *, size_t, const KerberosTime *, size_t *);
 size_t length_KerberosTime(const KerberosTime *);
-int copy_KerberosTime(const KerberosTime *, KerberosTime *);
+int    copy_KerberosTime  (const KerberosTime *, KerberosTime *);
+void   free_KerberosTime  (KerberosTime *);
 
 
 /*
-AuthorizationData ::= SEQUENCE OF SEQUENCE {
-  ad-type[0]      INTEGER,
-  ad-data[1]      OCTET STRING
+AuthorizationDataElement ::= SEQUENCE {
+  ad-type         [0] krb5int32,
+  ad-data         [1] OCTET STRING,
 }
 */
 
+typedef struct AuthorizationDataElement {
+  krb5int32 ad_type;
+  heim_octet_string ad_data;
+} AuthorizationDataElement;
+
+int    decode_AuthorizationDataElement(const unsigned char *, size_t, AuthorizationDataElement *, size_t *);
+int    encode_AuthorizationDataElement(unsigned char *, size_t, const AuthorizationDataElement *, size_t *);
+size_t length_AuthorizationDataElement(const AuthorizationDataElement *);
+int    copy_AuthorizationDataElement  (const AuthorizationDataElement *, AuthorizationDataElement *);
+void   free_AuthorizationDataElement  (AuthorizationDataElement *);
+
+
+/*
+AuthorizationData ::= SEQUENCE OF AuthorizationDataElement
+*/
+
 typedef struct AuthorizationData {
-    unsigned int len;
-    struct {
-       int ad_type;
-       octet_string ad_data;
-    } *val;
+  unsigned int len;
+  AuthorizationDataElement *val;
 } AuthorizationData;
 
-int encode_AuthorizationData(unsigned char *, size_t,
-                            const AuthorizationData *, size_t *);
-int decode_AuthorizationData(const unsigned char *, size_t,
-                            AuthorizationData *, size_t *);
-void free_AuthorizationData(AuthorizationData *);
+int   add_AuthorizationData  (AuthorizationData *, const AuthorizationDataElement *);
+int   remove_AuthorizationData  (AuthorizationData *, unsigned int);
+int    decode_AuthorizationData(const unsigned char *, size_t, AuthorizationData *, size_t *);
+int    encode_AuthorizationData(unsigned char *, size_t, const AuthorizationData *, size_t *);
 size_t length_AuthorizationData(const AuthorizationData *);
-int copy_AuthorizationData(const AuthorizationData *, AuthorizationData *);
+int    copy_AuthorizationData  (const AuthorizationData *, AuthorizationData *);
+void   free_AuthorizationData  (AuthorizationData *);
 
 
 /*
@@ -342,19 +652,49 @@ APOptions ::= BIT STRING {
 */
 
 typedef struct APOptions {
-    unsigned int reserved:1;
-    unsigned int use_session_key:1;
-    unsigned int mutual_required:1;
+  unsigned int reserved:1;
+  unsigned int use_session_key:1;
+  unsigned int mutual_required:1;
+  unsigned int _unused3:1;
+  unsigned int _unused4:1;
+  unsigned int _unused5:1;
+  unsigned int _unused6:1;
+  unsigned int _unused7:1;
+  unsigned int _unused8:1;