From 6441ad46e842e50e618843af0652fd5d6f24b565 Mon Sep 17 00:00:00 2001 From: Theodore Tso Date: Wed, 19 Apr 1995 21:49:57 +0000 Subject: [PATCH] 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. git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@5380 dc483132-0cff-0310-8789-dd5450dbe970 --- src/lib/krb5/asn.1/ChangeLog | 26 +++++++++++ src/lib/krb5/asn.1/asn1_k_decode.c | 70 +++++++++++++++++++++++++++--- src/lib/krb5/asn.1/asn1_k_encode.c | 17 +++++++- src/lib/krb5/asn.1/krbasn1.h | 10 +++++ 4 files changed, 117 insertions(+), 6 deletions(-) diff --git a/src/lib/krb5/asn.1/ChangeLog b/src/lib/krb5/asn.1/ChangeLog index c19deaad2..87eb0421d 100644 --- a/src/lib/krb5/asn.1/ChangeLog +++ b/src/lib/krb5/asn.1/ChangeLog @@ -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. diff --git a/src/lib/krb5/asn.1/asn1_k_decode.c b/src/lib/krb5/asn.1/asn1_k_decode.c index 159667923..2100b4558 100644 --- a/src/lib/krb5/asn.1/asn1_k_decode.c +++ b/src/lib/krb5/asn.1/asn1_k_decode.c @@ -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> 8) & 0xff] << 16) | + (asn1_swbits[(f >> 16) & 0xff] << 8) | asn1_swbits[(f >> 24) & 0xff]; + *val = f; return 0; } diff --git a/src/lib/krb5/asn.1/asn1_k_encode.c b/src/lib/krb5/asn.1/asn1_k_encode.c index 731083a99..0c92cac04 100644 --- a/src/lib/krb5/asn.1/asn1_k_encode.c +++ b/src/lib/krb5/asn.1/asn1_k_encode.c @@ -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; diff --git a/src/lib/krb5/asn.1/krbasn1.h b/src/lib/krb5/asn.1/krbasn1.h index eb63258fc..ec44baae1 100644 --- a/src/lib/krb5/asn.1/krbasn1.h +++ b/src/lib/krb5/asn.1/krbasn1.h @@ -19,6 +19,14 @@ */ #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 -- 2.26.2