Full_Name: Emmanuel Lecjarny Version: 2.4.44 OS: URL: ftp://ftp.openldap.org/incoming/ Submission from: (NULL) (90.92.161.247)
IMO, the code that deal with tags in the lber decode.c ber_tag_and_rest() method is incorrectly decoding tags that are longer than 1 byte. Not that it is a huge problem for OpenLDAP, because we always use 1 byte long tags, but from the ASN.1 BER decoding POV, that wilbrbreak when having a 2 bytes long tag :
116 do { 117 if ( rest <= 0 ) { 118 break; 119 } 120 tag <<= 8; 121 tag |= *ptr++ & 0xffU; 122 rest--; 123 124 if ( ! (tag & LBER_MORE_TAG_MASK) ) { 125 goto done; 126 } 127 } while ( tag <= (ber_tag_t)-1 / 256 );
should read
114 tag = (ber_tag_t) 0x00U; 115 116 do { 117 if ( rest <= 0 ) { 118 break; 119 } 120 tag <<= 7; 121 tag |= *ptr++ & 0x7fU; 122 rest--; 123 124 if ( ! (tag & LBER_MORE_TAG_MASK) ) { 125 goto done; 126 } 127 } while ( tag <= (ber_tag_t)-1 / 256 );
The reason being that BER encoding for Tags when longer than 1 byte looks like :
[class|P/C|11111] - [1|uuu uuuu] - [1|uuu uuuu] - [1|uuu uuuu] - ... - [0|uuu uuuu] byte 1 byte 2 byte 3 byte 4 byte N
and the 'uuu uuuu' parts are only 7 bits long.