[Date Prev][Date Next] [Chronological] [Thread] [Top]

(ITS#8516) TAG decoding incorrect when longer than 1 byte



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.