asn1_k_decode.c (asn1_decode_krb5_flags): Make the function
authorTheodore Tso <tytso@mit.edu>
Wed, 19 Apr 1995 21:49:57 +0000 (21:49 +0000)
committerTheodore Tso <tytso@mit.edu>
Wed, 19 Apr 1995 21:49:57 +0000 (21:49 +0000)
accept bit strings which are less 32 bits long.
(RFC-1510 makes no guarantee that the length of the bit
string must be 32 bits long; the old code required that
the length of the bit string must be exactly 32 bits.)

Flip the bits with respect to a 32-bit boundary, since
that's what the old ASN.1 glue code did.  (The values in
fieldbits.h are encoded backwards, for no good reason.)
If BACKWARDS_BITMASK_COMPAT is defined, then only flip the
bits if the high 16 bits are clear and there are some bits set
in the low 16 bits.  This preserves interoperabilty with
the old beta 4 distribution, which sent the bit string
without flipping them around.

asn1_k_encode.c (asn1_encode_krb5_flags): Flip the bits with
respect to a 32-bit boundary, since that's what the
old ASN.1 glue code did.  (The values in fieldbits.h
are encoded backwards, for no good reason.)

krb_asn1.h: #define BACKWARDS_BITMASK_COMPAT.  Add extern
declaration for asn1_swbits, which is needed for the
bit reversing code.

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

src/lib/krb5/asn.1/ChangeLog
src/lib/krb5/asn.1/asn1_k_decode.c
src/lib/krb5/asn.1/asn1_k_encode.c
src/lib/krb5/asn.1/krbasn1.h

index c19deaad261e1a10edad0a120b7401fe88804e28..87eb0421d27442d61d06d2d8643e4c659dc3ac19 100644 (file)
@@ -1,3 +1,29 @@
+Tue Apr 18 21:46:30 1995  Theodore Y. Ts'o  (tytso@dcl)
+
+       * asn1_k_decode.c (asn1_decode_krb5_flags): Make the function
+               accept bit strings which are less 32 bits long.
+               (RFC-1510 makes no guarantee that the length of the bit
+               string must be 32 bits long; the old code required that
+               the length of the bit string must be exactly 32 bits.)
+
+               Flip the bits with respect to a 32-bit boundary, since
+               that's what the old ASN.1 glue code did.  (The values in 
+               fieldbits.h are encoded backwards, for no good reason.)
+               If BACKWARDS_BITMASK_COMPAT is defined, then only flip the 
+               bits if the high 16 bits are clear and there are some bits set
+               in the low 16 bits.  This preserves interoperabilty with
+               the old beta 4 distribution, which sent the bit string
+               without flipping them around.
+
+       * asn1_k_encode.c (asn1_encode_krb5_flags): Flip the bits with
+               respect to a 32-bit boundary, since that's what the
+               old ASN.1 glue code did.  (The values in fieldbits.h
+               are encoded backwards, for no good reason.)
+
+       * krb_asn1.h: #define BACKWARDS_BITMASK_COMPAT.  Add extern
+               declaration for asn1_swbits, which is needed for the
+               bit reversing code.
+
 Thu Apr 13 20:13:38 1995 Keith Vetter (keithv@fusion.com)
 
        * asn1_k_decode.c: fixed up 'unreferenced local variable' problems.
index 159667923d4d9a99c0565f306dc5892b78b1a1de..2100b4558fbd73352a280af8dbac7b02d84ca918 100644 (file)
@@ -265,12 +265,59 @@ asn1_error_code asn1_decode_encrypted_data(buf, val)
   cleanup();
 }
 
+static asn1_octet asn1_pad_mask[] = { 0xFF, 0x7F, 0x3F, 0x1F, 
+                                     0x0F, 0x07, 0x03, 0x01 };
+
+asn1_octet asn1_swbits[256] = {
+0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
+0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
+0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
+0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
+0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
+0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
+0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
+0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
+0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
+0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
+0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
+0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
+0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
+0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
+0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
+0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
+0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
+0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
+0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
+0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
+0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
+0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
+0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
+0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
+0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
+0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
+0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
+0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
+0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
+0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
+0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
+0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff,
+};
+
+/*
+ * NOTE!!!! for historical reasons, krb5_flags are bitreversed 
+ * around a 32-bit boundary in the MIT implementation.  Hence, bit #0 is 
+ * really 0x80000000.  There's no good reason for it, but it's too hard 
+ * to change things now.....
+ * 
+ * People should beware of this before using asn1_decode_krb5_flags to decode
+ * other ASN.1 bit strings, since behavior is hard coded in this function.
+ */ 
 asn1_error_code asn1_decode_krb5_flags(buf, val)
      asn1buf * buf;
      krb5_flags * val;
 {
   setup();
-  asn1_octet o;
+  asn1_octet o, pad;
   int i;
   krb5_flags f=0;
   unused_var(taglen);
@@ -279,17 +326,30 @@ asn1_error_code asn1_decode_krb5_flags(buf, val)
   if(retval) return retval;
   if(class != UNIVERSAL || construction != PRIMITIVE ||
      tagnum != ASN1_BITSTRING) return ASN1_BAD_ID;
-  if(length != 5) return ASN1_BAD_LENGTH;
+  if (length < 2 || length > 5) return ASN1_BAD_LENGTH;
 
-  retval = asn1buf_remove_octet(buf,&o); /* # of padding bits */
+  retval = asn1buf_remove_octet(buf,&pad); /* # of padding bits */
   if(retval) return retval;    /*  should be 0 */
-  if(o != 0) return ASN1_BAD_FORMAT;
+  if (pad > 7) return ASN1_BAD_FORMAT;
+
+  length -= 2; /* -1 for #pad bits, -1 for the last byte */
 
-  for(i=0; i<4; i++){
+  for(i=0; i<length; i++){
     retval = asn1buf_remove_octet(buf,&o);
     if(retval) return retval;
     f = (f<<8) | ((krb5_flags)o&0xFF);
   }
+  /* handle last byte separately, to mask out the padding bits */
+  retval = asn1buf_remove_octet(buf,&o);
+  if(retval) return retval;
+  f = (f<<8) | ((krb5_flags)o&asn1_pad_mask[pad]);
+
+#ifdef BACKWARD_BITMASK_COMPAT
+  if ((f & 0xFFFF0000 == 0) && (f & 0xFFFF != 0))
+#endif
+  f = (asn1_swbits[(f & 0xff)] << 24) | (asn1_swbits[(f >> 8) & 0xff] << 16) |
+      (asn1_swbits[(f >> 16) & 0xff] << 8) | asn1_swbits[(f >> 24) & 0xff];
+
   *val = f;
   return 0;
 }
index 731083a99125466afd2992a71ea95937a27fa0c8..0c92cac0451e0d9a27b074303544c6363a435a77 100644 (file)
@@ -235,15 +235,30 @@ asn1_error_code asn1_encode_encrypted_data(buf, val, retlen)
   asn1_cleanup();
 }
 
+/*
+ * NOTE!!!! for historical reasons, krb5_flags are bitreversed 
+ * around a 32-bit boundary in the MIT implementation.  Hence, bit #0 is 
+ * really 0x80000000, so we need to do a 32 bit reverse operation before 
+ * encoding the bit string..  There's no good reason for it, but it's too 
+ * hard to change things now, since the flags are used in other places.
+ * 
+ * People should beware of this before using asn1_encode_krb5_flags to encode
+ * other ASN.1 bit strings, since behavior is hard-coded into this function.
+ */ 
 asn1_error_code asn1_encode_krb5_flags(buf, val, retlen)
      asn1buf * buf;
      const krb5_flags val;
      int * retlen;
 {
   asn1_setup();
-  krb5_flags valcopy = val;
+  krb5_flags valcopy;
   int i;
 
+  valcopy = ((asn1_swbits[(val & 0xff)] << 24) | 
+            (asn1_swbits[(val >> 8) & 0xff] << 16) |
+            (asn1_swbits[(val >> 16) & 0xff] << 8) | 
+            asn1_swbits[(val >> 24) & 0xff]);
+
   for(i=0; i<4; i++){
     retval = asn1buf_insert_octet(buf,(asn1_octet) (valcopy&0xFF));
     if(retval) return retval;
index eb63258fc55bdb00d81a4f91d417229a4c5124f4..ec44baae1c8d1c6bd0df4ee8e8748e3fcad97fb2 100644 (file)
  */
 #define KRB5_ENCKRB5KDCREPPART_COMPAT
 
+/* 
+ * The hand-coded parser used in the Beta 4 distribution didn't
+ * reverse the order of the bit string fields.  This define allows partial
+ * interoperability with the Beta 4 distribution by doing a bit reversal
+ * on bitfields which have bits set in the high 16 bits.
+ */
+#define BACKWARD_BITMASK_COMPAT
+
 /*
  * If KRB5_MSGTYPE_STRICT is defined, then be strict about checking
  * the msgtype fields.  Unfortunately, there old versions of Kerberos
@@ -39,6 +47,8 @@ typedef int asn1_tagnum;
 #define ASN1_TAGNUM_CEILING INT_MAX
 #define ASN1_TAGNUM_MAX (ASN1_TAGNUM_CEILING-1)
 
+extern asn1_octet asn1_swbits[256];
+
 /* This is Kerberos Version 5 */
 #define KVNO 5