Rewrite asn1_get_tag interface to use a structure pointer rather than several
authorKen Raeburn <raeburn@mit.edu>
Wed, 12 Mar 2003 04:33:30 +0000 (04:33 +0000)
committerKen Raeburn <raeburn@mit.edu>
Wed, 12 Mar 2003 04:33:30 +0000 (04:33 +0000)
pointer variables for the returned data.  Use the structure in the caller when
straightforward; in cases where macros use different but overlapping sets of
automatic scalar variables in one file, copy the values out of the structures
for now, until they can be analyzed more carefully.

* asn1_get.c (asn1_get_tag): Deleted.
(asn1_get_tag_2): Renamed from asn1_get_tag_indef, now uses a pointer to
taginfo rather than a bunch of pointer args.
(asn1_get_id, asn1_get_length): Folded into asn1_get_tag_2.
(asn1_get_sequence): Call asn1_get_tag_2.
* asn1_get.h (taginfo): New structure.
(asn1_get_tag_indef, asn1_get_tag, asn1_get_id, asn1_get_length): Declarations
deleted.
(asn1_get_tag_2): Declare.
* asn1_decode.c (setup): Declare only a taginfo variable.
(asn1class, construction, tagnum, length): New macros.
(tag): Call asn1_get_tag_2.
* asn1_k_decode.c (next_tag, get_eoc, apptag, end_sequence_of,
end_sequence_of_no_tagvars, asn1_decode_krb5_flags): Call asn1_get_tag_2; if no
error, copy out values into scalar variables.
(asn1_decode_ticket): Call asn1_get_tag_2.
* asn1buf.c (asn1buf_skiptail): Call asn1_get_tag_2.
* krb5_decode.c (check_apptag, next_tag, get_eoc): Call asn1_get_tag_2; if no
error, copy out values into scalar variables.
(decode_krb5_enc_kdc_rep_part): Call asn1_get_tag_2.

git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@15274 dc483132-0cff-0310-8789-dd5450dbe970

src/lib/krb5/asn.1/ChangeLog
src/lib/krb5/asn.1/asn1_decode.c
src/lib/krb5/asn.1/asn1_get.c
src/lib/krb5/asn.1/asn1_get.h
src/lib/krb5/asn.1/asn1_k_decode.c
src/lib/krb5/asn.1/asn1buf.c
src/lib/krb5/asn.1/krb5_decode.c

index 50524055cf56431baecf9fbc14513950afe42b21..b1ff161c4f61e1b529eee24cde6fd89bb4cbc8d3 100644 (file)
@@ -1,3 +1,28 @@
+2003-03-11  Ken Raeburn  <raeburn@mit.edu>
+
+       * asn1_get.c (asn1_get_tag): Deleted.
+       (asn1_get_tag_2): Renamed from asn1_get_tag_indef, now uses a
+       pointer to taginfo rather than a bunch of pointer args.
+       (asn1_get_id, asn1_get_length): Folded into asn1_get_tag_2.
+       (asn1_get_sequence): Call asn1_get_tag_2.
+       * asn1_get.h (taginfo): New structure.
+       (asn1_get_tag_indef, asn1_get_tag, asn1_get_id, asn1_get_length):
+       Declarations deleted.
+       (asn1_get_tag_2): Declare.
+       * asn1_decode.c (setup): Declare only a taginfo variable.
+       (asn1class, construction, tagnum, length): New macros.
+       (tag): Call asn1_get_tag_2.
+       * asn1_k_decode.c (next_tag, get_eoc, apptag, end_sequence_of,
+       end_sequence_of_no_tagvars, asn1_decode_krb5_flags): Call
+       asn1_get_tag_2; if no error, copy out values into scalar
+       variables.
+       (asn1_decode_ticket): Call asn1_get_tag_2.
+       * asn1buf.c (asn1buf_skiptail): Call asn1_get_tag_2.
+       * krb5_decode.c (check_apptag, next_tag, get_eoc): Call
+       asn1_get_tag_2; if no error, copy out values into scalar
+       variables.
+       (decode_krb5_enc_kdc_rep_part): Call asn1_get_tag_2.
+
 2003-01-10  Ken Raeburn  <raeburn@mit.edu>
 
        * Makefile.in: Add AC_SUBST_FILE marker for libobj_frag.
index f8170830b6715a10fe4aeab5534c3ce64481cb7d..56904c5eea1b29a1ec35a24da0fe97f53179b03b 100644 (file)
 
 #define setup()\
 asn1_error_code retval;\
-asn1_class asn1class;\
-asn1_construction construction;\
-asn1_tagnum tagnum;\
-unsigned int length
+taginfo tinfo
+
+#define asn1class      (tinfo.asn1class)
+#define construction   (tinfo.construction)
+#define tagnum         (tinfo.tagnum)
+#define length         (tinfo.length)
 
 #define tag(type)\
-retval = asn1_get_tag(buf,&asn1class,&construction,&tagnum,&length);\
+retval = asn1_get_tag_2(buf,&tinfo);\
 if(retval) return retval;\
 if(asn1class != UNIVERSAL || construction != PRIMITIVE || tagnum != type)\
   return ASN1_BAD_ID
index e90ac6b06e3f7368a36e1f286efd5649decb76d7..d5a7ca40057779906b1811722a25ff89b34e30d9 100644 (file)
 #include "asn1_get.h"
 
 asn1_error_code
-asn1_get_tag_indef(asn1buf *buf, asn1_class *asn1class,
-                  asn1_construction *construction, asn1_tagnum *tagnum,
-                  unsigned int *retlen, int *indef)
+asn1_get_tag_2(asn1buf *buf, taginfo *t)
 {
-  asn1_error_code retval;
-  
-  if (buf == NULL || buf->base == NULL ||
-      buf->bound - buf->next + 1 <= 0) {
-    *tagnum = ASN1_TAGNUM_CEILING; /* emphatically not an EOC tag */
-    if (asn1class != NULL)
-      *asn1class = UNIVERSAL;
-    if (construction != NULL)
-      *construction = PRIMITIVE;
-    if (retlen != NULL)
-      *retlen = 0;
-    if (indef != NULL)
-      *indef = 0;
-    return 0;
-  }
-  retval = asn1_get_id(buf,asn1class,construction,tagnum);
-  if(retval) return retval;
-  retval = asn1_get_length(buf,retlen,indef);
-  if(retval) return retval;
-  if (indef != NULL && *indef &&
-      construction != NULL && *construction != CONSTRUCTED)
-    return ASN1_MISMATCH_INDEF;
-  return 0;
-}
-
-asn1_error_code
-asn1_get_tag(asn1buf *buf, asn1_class *asn1class,
-            asn1_construction *construction, asn1_tagnum *tagnum,
-            unsigned int *retlen)
-{
-  int indef;
-
-  return asn1_get_tag_indef(buf, asn1class, construction, tagnum, retlen,
-                           &indef);
-}
-
-asn1_error_code asn1_get_sequence(asn1buf *buf, unsigned int *retlen, int *indef)
-{
-  asn1_error_code retval;
-  asn1_class asn1class;
-  asn1_construction construction;
-  asn1_tagnum tagnum;
-
-  retval = asn1_get_tag_indef(buf,&asn1class,&construction,&tagnum,retlen,indef);
-  if(retval) return retval;
-  if(retval) return (krb5_error_code)retval;
-  if(asn1class != UNIVERSAL || construction != CONSTRUCTED ||
-     tagnum != ASN1_SEQUENCE) return ASN1_BAD_ID;
-  return 0;
-}
-
-/****************************************************************/
-/* Private Procedures */
+    asn1_error_code retval;
 
-asn1_error_code asn1_get_id(asn1buf *buf, asn1_class *asn1class,
-                           asn1_construction *construction,
-                           asn1_tagnum *tagnum)
-{
-  asn1_error_code retval;
-  asn1_tagnum tn=0;
-  asn1_octet o;
+    if (buf == NULL || buf->base == NULL ||
+       buf->bound - buf->next + 1 <= 0) {
+       t->tagnum = ASN1_TAGNUM_CEILING; /* emphatically not an EOC tag */
+       t->asn1class = UNIVERSAL;
+       t->construction = PRIMITIVE;
+       t->length = 0;
+       t->indef = 0;
+       return 0;
+    }
+    {
+       /* asn1_get_id(buf, t) */
+       asn1_tagnum tn=0;
+       asn1_octet o;
 
 #define ASN1_CLASS_MASK 0xC0
 #define ASN1_CONSTRUCTION_MASK 0x20
 #define ASN1_TAG_NUMBER_MASK 0x1F
 
-  retval = asn1buf_remove_octet(buf,&o);
-  if(retval) return retval;
+       retval = asn1buf_remove_octet(buf,&o);
+       if (retval)
+           return retval;
 
-  if(asn1class != NULL)
-    *asn1class = (asn1_class)(o&ASN1_CLASS_MASK);
-  if(construction != NULL)
-    *construction = (asn1_construction)(o&ASN1_CONSTRUCTION_MASK);
-  if((o&ASN1_TAG_NUMBER_MASK) != ASN1_TAG_NUMBER_MASK){
-    /* low-tag-number form */
-    if(tagnum != NULL) *tagnum = (asn1_tagnum)(o&ASN1_TAG_NUMBER_MASK);
-  }else{
-    /* high-tag-number form */
-    do{
-      retval = asn1buf_remove_octet(buf,&o);
-      if(retval) return retval;
-      tn = (tn<<7) + (asn1_tagnum)(o&0x7F);
-    }while(tn&0x80);
-    if(tagnum != NULL) *tagnum = tn;
-  }
-  return 0;
-}
+       t->asn1class = (asn1_class)(o&ASN1_CLASS_MASK);
+       t->construction = (asn1_construction)(o&ASN1_CONSTRUCTION_MASK);
+       if ((o&ASN1_TAG_NUMBER_MASK) != ASN1_TAG_NUMBER_MASK){
+           /* low-tag-number form */
+           t->tagnum = (asn1_tagnum)(o&ASN1_TAG_NUMBER_MASK);
+       } else {
+           /* high-tag-number form */
+           do {
+               retval = asn1buf_remove_octet(buf,&o);
+               if (retval) return retval;
+               tn = (tn<<7) + (asn1_tagnum)(o&0x7F);
+           }while(tn&0x80);
+           t->tagnum = tn;
+       }
+    }
 
-asn1_error_code asn1_get_length(asn1buf *buf, unsigned int *retlen, int *indef)
-{
-  asn1_error_code retval;
-  asn1_octet o;
+    {
+       /* asn1_get_length(buf, t) */
+       asn1_octet o;
 
-  if (indef != NULL)
-    *indef = 0;
-  retval = asn1buf_remove_octet(buf,&o);
-  if(retval) return retval;
-  if((o&0x80) == 0){
-    if(retlen != NULL) *retlen = (int)(o&0x7F);
-  }else{
-    int num;
-    int len=0;
+       t->indef = 0;
+       retval = asn1buf_remove_octet(buf,&o);
+       if (retval) return retval;
+       if ((o&0x80) == 0) {
+           t->length = (int)(o&0x7F);
+       } else {
+           int num;
+           int len=0;
     
-    for(num = (int)(o&0x7F); num>0; num--){
-      retval = asn1buf_remove_octet(buf,&o);
-      if(retval) return retval;
-      len = (len<<8) + (int)o;
+           for (num = (int)(o&0x7F); num>0; num--) {
+               retval = asn1buf_remove_octet(buf,&o);
+               if(retval) return retval;
+               len = (len<<8) + (int)o;
+           }
+           if (len < 0)
+               return ASN1_OVERRUN;
+           if (!len)
+               t->indef = 1;
+           t->length = len;
+       }
     }
-    if (len < 0)
-      return ASN1_OVERRUN;
-    if (indef != NULL && !len)
-      *indef = 1;
-    if(retlen != NULL) *retlen = len;
-  }
-  return 0;
+    if (t->indef && t->construction != CONSTRUCTED)
+       return ASN1_MISMATCH_INDEF;
+    return 0;
+}
+
+asn1_error_code asn1_get_sequence(asn1buf *buf, unsigned int *retlen, int *indef)
+{
+    taginfo t;
+    asn1_error_code retval;
+
+    retval = asn1_get_tag_2(buf, &t);
+    if (retval)
+       return retval;
+    if (t.asn1class != UNIVERSAL || t.construction != CONSTRUCTED ||
+       t.tagnum != ASN1_SEQUENCE)
+       return ASN1_BAD_ID;
+    if (retlen)
+       *retlen = t.length;
+    if (indef)
+       *indef = t.indef;
+    return 0;
 }
index 169490ac7a91c5bd029f27929b8438a85a0fb911..50a1b75cedbd5c36601b363753daaff20f5dba73 100644 (file)
 #include "krbasn1.h"
 #include "asn1buf.h"
 
+typedef struct {
+    asn1_class asn1class;
+    asn1_construction construction;
+    asn1_tagnum tagnum;
+    unsigned int length;
+    int indef;
+} taginfo;
+
+asn1_error_code asn1_get_tag_2 (asn1buf *buf, taginfo *tinfo);
+
+#if 0
 asn1_error_code asn1_get_tag_indef
        (asn1buf *buf,
                   asn1_class *Class,
                   asn1_construction *construction,
                   asn1_tagnum *tagnum,
                   unsigned int *retlen, int *indef);
+
 asn1_error_code asn1_get_tag
        (asn1buf *buf,
                   asn1_class *Class,
@@ -53,6 +65,7 @@ asn1_error_code asn1_get_tag
             If *buf is empty to begin with,
              *tagnum is set to ASN1_TAGNUM_CEILING.
             Returns ASN1_OVERRUN if *buf is exhausted during the parse. */
+#endif
 
 asn1_error_code asn1_get_sequence
        (asn1buf *buf, unsigned int *retlen, int *indef);
@@ -61,27 +74,4 @@ asn1_error_code asn1_get_sequence
               doesn't have a sequence ID.  If retlen != NULL, the
              associated length is returned in *retlen. */
 
-/****************************************************************/
-/* Private Procedures */
-
-asn1_error_code asn1_get_id
-       (asn1buf *buf,
-                  asn1_class *Class,
-                  asn1_construction *construction,
-                  asn1_tagnum *tagnum);
-/* requires  *buf is allocated
-   effects   Decodes the group of identifier octets at *buf's
-              current position.  If class != NULL, returns the class
-              in *Class.  Similarly, the construction and tag number
-              are returned in *construction and *tagnum, respectively.
-            Returns ASN1_OVERRUN if *buf is exhausted. */
-
-asn1_error_code asn1_get_length
-       (asn1buf *buf, unsigned int *retlen, int *indef);
-/* requires  *buf is allocated
-   effects   Decodes the group of length octets at *buf's
-              current position.  If retlen != NULL, the
-             length is returned in *retlen.
-            Returns ASN1_OVERRUN if *buf is exhausted. */
-
 #endif
index 0917d71e283ff841d158aa941e63c979221e37aa..c64ebb84e025ccc0ad967678a80f350a89ab5356 100644 (file)
 #define unused_var(x) if (0) { x = 0; x = x - x; }
 
 /* This is used for prefetch of next tag in sequence. */
-#define next_tag()                                                     \
-  retval = asn1_get_tag_indef(&subbuf, &asn1class, &construction,      \
-                             &tagnum, &taglen, &indef);                \
-  if (retval) return retval;
+#define next_tag()                                                             \
+{ taginfo t2;                                                                  \
+  retval = asn1_get_tag_2(&subbuf, &t2);                                       \
+  if (retval) return retval;                                                   \
+  /* Copy out to match previous functionality, until better integrated.  */    \
+  asn1class = t2.asn1class;                                                    \
+  construction = t2.construction;                                              \
+  tagnum = t2.tagnum;                                                          \
+  taglen = t2.length;                                                          \
+  indef = t2.indef;                                                            \
+}
 
 /* Force check for EOC tag. */
-#define get_eoc()                                                      \
-  retval = asn1_get_tag_indef(&subbuf, &asn1class, &construction,      \
-                             &tagnum, &taglen, &indef);                \
-  if (retval) return retval;                                           \
-  if (asn1class != UNIVERSAL || tagnum || indef)                       \
-    return ASN1_MISSING_EOC
+#define get_eoc()                                                                      \
+    {                                                                                  \
+       taginfo t3;                                                                     \
+       retval = asn1_get_tag_2(&subbuf, &t3);                                          \
+       if(retval) return retval;                                                       \
+        if (t3.asn1class != UNIVERSAL || t3.tagnum || t3.indef)                                \
+           return ASN1_MISSING_EOC;                                                    \
+        /* Copy out to match previous functionality, until better integrated.  */      \
+       asn1class = t3.asn1class;                                                       \
+       construction = t3.construction;                                                 \
+       tagnum = t3.tagnum;                                                             \
+       taglen = t3.length;                                                             \
+       indef = t3.indef;                                                               \
+    }
 
 #define alloc_field(var, type)                 \
   var = (type*)calloc(1, sizeof(type));                \
   if ((var) == NULL) return ENOMEM
 
 /* Fetch an expected APPLICATION class tag and verify. */
-#define apptag(tagexpect)                                                 \
-  retval = asn1_get_tag(buf, &asn1class, &construction, &tagnum, &applen); \
-  if (retval) return retval;                                              \
-  if (asn1class != APPLICATION || construction != CONSTRUCTED ||          \
-      tagnum != (tagexpect)) return ASN1_BAD_ID
+#define apptag(tagexpect)                                                              \
+  {                                                                                    \
+      taginfo t1;                                                                      \
+      retval = asn1_get_tag_2(buf, &t1);                                               \
+      if (retval) return retval;                                                       \
+      if (t1.asn1class != APPLICATION || t1.construction != CONSTRUCTED ||             \
+         t1.tagnum != (tagexpect)) return ASN1_BAD_ID;                                 \
+      /* Copy out to match previous functionality, until better integrated.  */                \
+      asn1class = t1.asn1class;                                                                \
+      construction = t1.construction;                                                  \
+      tagnum = t1.tagnum;                                                              \
+      applen = t1.length;                                                              \
+  }
 
 /**** normal fields ****/
 
  * Attempts to fetch an EOC tag, if any, and to sync over trailing
  * garbage, if any.
  */
-#define end_sequence_of(buf)                                           \
-  retval = asn1_get_tag_indef(&seqbuf, &asn1class, &construction,      \
-                             &tagnum, &taglen, &indef);                \
-  if (retval) return retval;                                           \
-  retval = asn1buf_sync(buf, &seqbuf, asn1class, tagnum,               \
-                       length, indef, seqofindef);                     \
+#define end_sequence_of(buf)                                                   \
+  {                                                                            \
+      taginfo t4;                                                              \
+      retval = asn1_get_tag_2(&seqbuf, &t4);                                   \
+      if (retval) return retval;                                               \
+      /* Copy out to match previous functionality, until better integrated.  */        \
+      asn1class = t4.asn1class;                                                        \
+      construction = t4.construction;                                          \
+      tagnum = t4.tagnum;                                                      \
+      taglen = t4.length;                                                      \
+      indef = t4.indef;                                                                \
+  }                                                                            \
+  retval = asn1buf_sync(buf, &seqbuf, asn1class, tagnum,                       \
+                       length, indef, seqofindef);                             \
   if (retval) return retval;
 
 /*
  * Like end_sequence_of(), but uses the different (non-shadowing)
  * variable names.
  */
-#define end_sequence_of_no_tagvars(buf)                                \
-  retval = asn1_get_tag_indef(&seqbuf, &eseqclass, &eseqconstr,        \
-                             &eseqnum, &eseqlen, &eseqindef);  \
-  if (retval) return retval;                                   \
-  retval = asn1buf_sync(buf, &seqbuf, eseqclass, eseqnum,      \
-                       eseqlen, eseqindef, seqofindef);        \
+#define end_sequence_of_no_tagvars(buf)                                                \
+  {                                                                            \
+      taginfo t5;                                                              \
+      retval = asn1_get_tag_2(&seqbuf, &t5);                                   \
+      if (retval) return retval;                                               \
+      /* Copy out to match previous functionality, until better integrated.  */        \
+      eseqclass = t5.asn1class;                                                        \
+      eseqconstr = t5.construction;                                            \
+      eseqnum = t5.tagnum;                                                     \
+      eseqlen = t5.length;                                                     \
+      eseqindef = t5.indef;                                                    \
+  }                                                                            \
+  retval = asn1buf_sync(buf, &seqbuf, eseqclass, eseqnum,                      \
+                       eseqlen, eseqindef, seqofindef);                        \
   if (retval) return retval;
 
 #define cleanup()                              \
@@ -374,16 +413,19 @@ asn1_error_code asn1_decode_encrypted_data(asn1buf *buf, krb5_enc_data *val)
 
 asn1_error_code asn1_decode_krb5_flags(asn1buf *buf, krb5_flags *val)
 {
-  setup();
+  asn1_error_code retval;
   asn1_octet unused, o;
+  taginfo t;
   int i;
   krb5_flags f=0;
-  unused_var(taglen);
+  unsigned int length;
 
-  retval = asn1_get_tag(buf,&asn1class,&construction,&tagnum,&length);
-  if(retval) return retval;
-  if(asn1class != UNIVERSAL || construction != PRIMITIVE ||
-     tagnum != ASN1_BITSTRING) return ASN1_BAD_ID;
+  retval = asn1_get_tag_2(buf, &t);
+  if (retval) return retval;
+  if (t.asn1class != UNIVERSAL || t.construction != PRIMITIVE ||
+      t.tagnum != ASN1_BITSTRING)
+      return ASN1_BAD_ID;
+  length = t.length;
 
   retval = asn1buf_remove_octet(buf,&unused); /* # of padding bits */
   if(retval) return retval;
@@ -472,9 +514,10 @@ asn1_error_code asn1_decode_ticket(asn1buf *buf, krb5_ticket *val)
     end_structure();
     val->magic = KV5M_TICKET;
   }
-  if(!applen) {
-    retval = asn1_get_tag(buf,&asn1class,&construction,&tagnum,NULL);
-    if (retval) return retval;
+  if (!applen) {
+      taginfo t;
+      retval = asn1_get_tag_2(buf, &t);
+      if (retval) return retval;
   }
   cleanup();
 }
index d28e310620b30a3c5e1167c56b041371e634b5d8..47e1902804b273bacdb0c1df45cc83b69da60498 100644 (file)
@@ -111,12 +111,8 @@ asn1_error_code asn1buf_sync(asn1buf *buf, asn1buf *subbuf,
 asn1_error_code asn1buf_skiptail(asn1buf *buf, const unsigned int length, const int indef)
 {
   asn1_error_code retval;
-  asn1_class asn1class;
-  asn1_construction construction;
-  asn1_tagnum tagnum;
-  unsigned int taglen;
+  taginfo t;
   int nestlevel;
-  int tagindef;
 
   nestlevel = 1 + indef;
   if (!indef) {
@@ -126,18 +122,17 @@ asn1_error_code asn1buf_skiptail(asn1buf *buf, const unsigned int length, const
       return ASN1_OVERRUN;
   }
   while (nestlevel > 0) {
-    retval = asn1_get_tag_indef(buf, &asn1class, &construction, &tagnum,
-                               &taglen, &tagindef);
+    retval = asn1_get_tag_2(buf, &t);
     if (retval) return retval;
-    if (!tagindef) {
-      if (taglen <= buf->bound - buf->next + 1)
-       buf->next += taglen;
+    if (!t.indef) {
+      if (t.length <= buf->bound - buf->next + 1)
+       buf->next += t.length;
       else
        return ASN1_OVERRUN;
     }
-    if (tagindef)
+    if (t.indef)
       nestlevel++;
-    if (asn1_is_eoc(asn1class, tagnum, tagindef))
+    if (asn1_is_eoc(t.asn1class, t.tagnum, t.indef))
       nestlevel--;             /* got an EOC encoding */
   }
   return 0;
index f2d916527c03c1d3d149f97b4ebd9e3d6deabf64..03a30295b82ddfa7ccbaa0b3f9e2c4d949640c21 100644 (file)
@@ -64,28 +64,46 @@ if((var) == NULL) clean_return(ENOMEM)
 
 /* process encoding header ***************************************/
 /* decode tag and check that it == [APPLICATION tagnum] */
-#define check_apptag(tagexpect)\
-retval = asn1_get_tag(&buf,&asn1class,&construction,&tagnum,NULL);\
-if(retval) clean_return(retval);\
-if(asn1class != APPLICATION || construction != CONSTRUCTED) \
-   clean_return(ASN1_BAD_ID);\
-if(tagnum != (tagexpect)) clean_return(KRB5_BADMSGTYPE)
+#define check_apptag(tagexpect)                                                \
+{                                                                      \
+    taginfo t1;                                                                \
+    retval = asn1_get_tag_2(&buf, &t1);                                        \
+    if (retval) clean_return (retval);                                 \
+    if (t1.asn1class != APPLICATION || t1.construction != CONSTRUCTED) \
+       clean_return(ASN1_BAD_ID);                                      \
+    if (t1.tagnum != (tagexpect)) clean_return(KRB5_BADMSGTYPE);       \
+    asn1class = t1.asn1class;                                          \
+    construction = t1.construction;                                    \
+    tagnum = t1.tagnum;                                                        \
+}
 
 
 
 /* process a structure *******************************************/
 
 /* decode an explicit tag and place the number in tagnum */
-#define next_tag()\
-retval = asn1_get_tag_indef(&subbuf,&asn1class,&construction,&tagnum,NULL,&indef);\
-if(retval) clean_return(retval)
+#define next_tag()                             \
+{ taginfo t2;                                  \
+  retval = asn1_get_tag_2(&subbuf, &t2);       \
+  if(retval) clean_return(retval);             \
+  asn1class = t2.asn1class;                    \
+  construction = t2.construction;              \
+  tagnum = t2.tagnum;                          \
+  indef = t2.indef;                            \
+}
 
 #define get_eoc()                                              \
-retval = asn1_get_tag_indef(&subbuf,&asn1class,&construction,  \
-                           &tagnum,NULL,&indef);               \
-if(retval) return retval;                                      \
-if(asn1class != UNIVERSAL || tagnum || indef)                  \
-  return ASN1_MISSING_EOC
+{                                                              \
+    taginfo t3;                                                        \
+    retval = asn1_get_tag_2(&subbuf, &t3);                     \
+    if (retval) return retval;                                 \
+    if (t3.asn1class != UNIVERSAL || t3.tagnum || t3.indef)    \
+        return ASN1_MISSING_EOC;                               \
+    asn1class = t3.asn1class;                                  \
+    construction = t3.construction;                            \
+    tagnum = t3.tagnum;                                                \
+    indef = t3.indef;                                          \
+}
 
 /* decode sequence header and initialize tagnum with the first field */
 #define begin_structure()\
@@ -306,14 +324,15 @@ error_out:
 
 krb5_error_code decode_krb5_enc_kdc_rep_part(const krb5_data *code, krb5_enc_kdc_rep_part **rep)
 {
-  setup_no_length();
+  taginfo t4;
+  setup_buf_only();
   alloc_field(*rep,krb5_enc_kdc_rep_part);
 
-  retval = asn1_get_tag(&buf,&asn1class,&construction,&tagnum,NULL);
-  if(retval) clean_return(retval);
-  if(asn1class != APPLICATION || construction != CONSTRUCTED) clean_return(ASN1_BAD_ID);
-  if(tagnum == 25) (*rep)->msg_type = KRB5_AS_REP;
-  else if(tagnum == 26) (*rep)->msg_type = KRB5_TGS_REP;
+  retval = asn1_get_tag_2(&buf, &t4);
+  if (retval) clean_return(retval);
+  if (t4.asn1class != APPLICATION || t4.construction != CONSTRUCTED) clean_return(ASN1_BAD_ID);
+  if (t4.tagnum == 25) (*rep)->msg_type = KRB5_AS_REP;
+  else if(t4.tagnum == 26) (*rep)->msg_type = KRB5_TGS_REP;
   else clean_return(KRB5_BADMSGTYPE);
 
   retval = asn1_decode_enc_kdc_rep_part(&buf,*rep);