1 /* decode.c - ber input decoding routines */
2 /* $OpenLDAP: pkg/ldap/libraries/liblber/decode.c,v 1.105.2.4 2008/02/11 23:26:41 kurt Exp $ */
3 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
5 * Copyright 1998-2008 The OpenLDAP Foundation.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted only as authorized by the OpenLDAP
12 * A copy of this license is available in the file LICENSE in the
13 * top-level directory of the distribution or, alternatively, at
14 * <http://www.OpenLDAP.org/license.html>.
16 /* Portions Copyright (c) 1990 Regents of the University of Michigan.
17 * All rights reserved.
19 * Redistribution and use in source and binary forms are permitted
20 * provided that this notice is preserved and that due credit is given
21 * to the University of Michigan at Ann Arbor. The name of the University
22 * may not be used to endorse or promote products derived from this
23 * software without specific prior written permission. This software
24 * is provided ``as is'' without express or implied warranty.
27 * This work was originally developed by the University of Michigan
28 * (as part of U-MICH LDAP).
35 #include <ac/stdlib.h>
37 #include <ac/stdarg.h>
38 #include <ac/string.h>
39 #include <ac/socket.h>
43 static ber_len_t ber_getnint
LDAP_P((
48 /* out->bv_len should be the buffer size on input */
50 ber_decode_oid( BerValue
*in
, BerValue
*out
)
52 const unsigned char *der
;
59 assert( out
!= NULL
);
61 /* need 4 chars/inbyte + \0 for input={7f 7f 7f...} */
62 if ( !out
->bv_val
|| (out
->bv_len
+3)/4 <= in
->bv_len
)
66 der
= (unsigned char *) in
->bv_val
;
68 for ( i
=0; i
< in
->bv_len
; i
++ ) {
70 if ( !( der
[i
] & 0x80 )) {
72 /* Initial "x.y": val=x*40+y, x<=2, y<40 if x=2 */
74 val1
= (val
< 80 ? val
/40 : 2);
76 ptr
+= sprintf( ptr
, "%u", val1
);
78 ptr
+= sprintf( ptr
, ".%lu", val
);
80 } else if ( val
- 1UL < LBER_OID_COMPONENT_MAX
>> 7 ) {
83 /* val would overflow, or is 0 from invalid initial 0x80 octet */
87 if ( ptr
== NULL
|| val
!= 0 )
90 out
->bv_len
= ptr
- out
->bv_val
;
94 /* return the tag - LBER_DEFAULT returned means trouble */
96 ber_get_tag( BerElement
*ber
)
102 assert( ber
!= NULL
);
103 assert( LBER_VALID( ber
) );
105 if ( ber_pvt_ber_remaining( ber
) < 1 ) {
109 if ( ber
->ber_ptr
== ber
->ber_buf
) {
110 tag
= *(unsigned char *)ber
->ber_ptr
;
116 if ( (tag
& LBER_BIG_TAG_MASK
) != LBER_BIG_TAG_MASK
) {
120 for ( i
= 1; i
< sizeof(ber_tag_t
); i
++ ) {
121 if ( ber_read( ber
, (char *) &xbyte
, 1 ) != 1 ) {
126 tag
|= 0x00ffUL
& (ber_tag_t
) xbyte
;
128 if ( ! (xbyte
& LBER_MORE_TAG_MASK
) ) {
134 if ( i
== sizeof(ber_tag_t
) ) {
142 ber_skip_tag( BerElement
*ber
, ber_len_t
*len
)
146 ber_len_t i
, noctets
;
147 unsigned char netlen
[sizeof(ber_len_t
)];
149 assert( ber
!= NULL
);
150 assert( len
!= NULL
);
151 assert( LBER_VALID( ber
) );
154 * Any ber element looks like this: tag length contents.
155 * Assuming everything's ok, we return the tag byte (we
156 * can assume a single byte), and return the length in len.
159 * 1) definite lengths
160 * 2) primitive encodings used whenever possible
166 * First, we read the tag.
169 if ( (tag
= ber_get_tag( ber
)) == LBER_DEFAULT
) {
174 * Next, read the length. The first byte contains the length of
175 * the length. If bit 8 is set, the length is the long form,
176 * otherwise it's the short form. We don't allow a length that's
177 * greater than what we can hold in a ber_len_t.
180 if ( ber_read( ber
, (char *) &lc
, 1 ) != 1 ) {
185 noctets
= (lc
& 0x7fU
);
187 if ( noctets
> sizeof(ber_len_t
) ) {
191 if( (unsigned) ber_read( ber
, (char *) netlen
, noctets
) != noctets
) {
195 for( i
= 0; i
< noctets
; i
++ ) {
204 /* BER element should have enough data left */
205 if( *len
> (ber_len_t
) ber_pvt_ber_remaining( ber
) ) {
208 ber
->ber_tag
= *(unsigned char *)ber
->ber_ptr
;
219 * This implementation assumes ber_skip_tag() only
220 * modifies ber_ptr field of the BerElement.
228 tag
= ber_skip_tag( ber
, len
);
241 unsigned char buf
[sizeof(ber_int_t
)];
243 assert( ber
!= NULL
);
244 assert( num
!= NULL
);
245 assert( LBER_VALID( ber
) );
248 * The tag and length have already been stripped off. We should
249 * be sitting right before len bytes of 2's complement integer,
250 * ready to be read straight into an int. We may have to sign
251 * extend after we read it in.
254 if ( len
> sizeof(ber_int_t
) ) {
258 /* read into the low-order bytes of our buffer */
259 if ( (ber_len_t
) ber_read( ber
, (char *) buf
, len
) != len
) {
264 /* sign extend if necessary */
266 ber_int_t netnum
= 0x80 & buf
[0] ? -1 : 0;
268 /* shift in the bytes */
269 for( i
=0 ; i
<len
; i
++ ) {
270 netnum
= (netnum
<< 8 ) | buf
[i
];
278 ber
->ber_tag
= *(unsigned char *)ber
->ber_ptr
;
291 assert( ber
!= NULL
);
292 assert( LBER_VALID( ber
) );
294 if ( (tag
= ber_skip_tag( ber
, &len
)) == LBER_DEFAULT
) {
298 if ( ber_getnint( ber
, num
, len
) != len
) {
310 return ber_get_int( ber
, num
);
322 assert( ber
!= NULL
);
323 assert( LBER_VALID( ber
) );
325 if ( (tag
= ber_skip_tag( ber
, &datalen
)) == LBER_DEFAULT
) {
329 /* must fit within allocated space with termination */
330 if ( datalen
>= *len
) {
334 if ( (ber_len_t
) ber_read( ber
, buf
, datalen
) != datalen
) {
337 ber
->ber_tag
= *(unsigned char *)ber
->ber_ptr
;
345 /* Definitions for get_string vector
347 * ChArray, BvArray, and BvVec are self-explanatory.
348 * BvOff is a struct berval embedded in an array of larger structures
349 * of siz bytes at off bytes from the beginning of the struct.
351 enum bgbvc
{ ChArray
, BvArray
, BvVec
, BvOff
};
353 /* Use this single cookie for state, to keep actual
354 * stack use to the absolute minimum.
356 typedef struct bgbvr
{
370 ber_get_stringbvl( bgbvr
*b
, ber_len_t
*rlen
)
376 struct berval bv
, *bvp
= NULL
;
378 /* For rewinding, just like ber_peek_tag() */
379 orig
= b
->ber
->ber_ptr
;
380 tag
= b
->ber
->ber_tag
;
382 if ( ber_first_element( b
->ber
, &len
, &last
) != LBER_DEFAULT
) {
383 for ( ; b
->ber
->ber_ptr
< last
; i
++ ) {
384 if (ber_skip_tag( b
->ber
, &len
) == LBER_DEFAULT
) break;
385 b
->ber
->ber_ptr
+= len
;
386 b
->ber
->ber_tag
= *(unsigned char *)b
->ber
->ber_ptr
;
390 if ( rlen
) *rlen
= i
;
399 /* Allocate the result vector */
402 *b
->res
.c
= ber_memalloc_x( (n
+1)*sizeof( char * ),
404 if ( *b
->res
.c
== NULL
) return LBER_DEFAULT
;
405 (*b
->res
.c
)[n
] = NULL
;
408 *b
->res
.ba
= ber_memalloc_x( (n
+1)*sizeof( struct berval
),
410 if ( *b
->res
.ba
== NULL
) return LBER_DEFAULT
;
411 (*b
->res
.ba
)[n
].bv_val
= NULL
;
414 *b
->res
.bv
= ber_memalloc_x( (n
+1)*sizeof( struct berval
*),
416 if ( *b
->res
.bv
== NULL
) return LBER_DEFAULT
;
417 (*b
->res
.bv
)[n
] = NULL
;
420 *b
->res
.ba
= ber_memalloc_x( (n
+1) * b
->siz
, b
->ber
->ber_memctx
);
421 if ( *b
->res
.ba
== NULL
) return LBER_DEFAULT
;
422 ((struct berval
*)((char *)(*b
->res
.ba
) + n
*b
->siz
+
423 b
->off
))->bv_val
= NULL
;
426 b
->ber
->ber_ptr
= orig
;
427 b
->ber
->ber_tag
= tag
;
428 ber_skip_tag( b
->ber
, &len
);
432 tag
= ber_next_element( b
->ber
, &len
, last
);
433 if ( ber_get_stringbv( b
->ber
, &bv
, b
->alloc
) == LBER_DEFAULT
) {
437 /* store my result */
440 (*b
->res
.c
)[n
] = bv
.bv_val
;
443 (*b
->res
.ba
)[n
] = bv
;
446 bvp
= ber_memalloc_x( sizeof( struct berval
), b
->ber
->ber_memctx
);
448 LBER_FREE(bv
.bv_val
);
451 (*b
->res
.bv
)[n
] = bvp
;
455 *(BerVarray
)((char *)(*b
->res
.ba
)+n
*b
->siz
+b
->off
) = bv
;
462 if (b
->alloc
|| b
->choice
== BvVec
) {
463 for (--n
; n
>=0; n
--) {
466 LBER_FREE((*b
->res
.c
)[n
]);
469 LBER_FREE((*b
->res
.ba
)[n
].bv_val
);
472 LBER_FREE((*b
->res
.bv
)[n
]->bv_val
);
473 LBER_FREE((*b
->res
.bv
)[n
]);
480 LBER_FREE(*b
->res
.c
);
486 ber_get_stringbv( BerElement
*ber
, struct berval
*bv
, int option
)
490 assert( ber
!= NULL
);
491 assert( bv
!= NULL
);
493 assert( LBER_VALID( ber
) );
495 if ( (tag
= ber_skip_tag( ber
, &bv
->bv_len
)) == LBER_DEFAULT
) {
500 if ( (ber_len_t
) ber_pvt_ber_remaining( ber
) < bv
->bv_len
) {
504 if ( option
& LBER_BV_ALLOC
) {
505 bv
->bv_val
= (char *) ber_memalloc_x( bv
->bv_len
+ 1,
507 if ( bv
->bv_val
== NULL
) {
511 if ( bv
->bv_len
> 0 && (ber_len_t
) ber_read( ber
, bv
->bv_val
,
512 bv
->bv_len
) != bv
->bv_len
)
514 LBER_FREE( bv
->bv_val
);
519 bv
->bv_val
= ber
->ber_ptr
;
520 ber
->ber_ptr
+= bv
->bv_len
;
522 ber
->ber_tag
= *(unsigned char *)ber
->ber_ptr
;
523 if ( !( option
& LBER_BV_NOTERM
))
524 bv
->bv_val
[bv
->bv_len
] = '\0';
530 ber_get_stringbv_null( BerElement
*ber
, struct berval
*bv
, int option
)
534 assert( ber
!= NULL
);
535 assert( bv
!= NULL
);
537 assert( LBER_VALID( ber
) );
539 if ( (tag
= ber_skip_tag( ber
, &bv
->bv_len
)) == LBER_DEFAULT
) {
544 if ( (ber_len_t
) ber_pvt_ber_remaining( ber
) < bv
->bv_len
) {
548 if ( bv
->bv_len
== 0 ) {
550 ber
->ber_tag
= *(unsigned char *)ber
->ber_ptr
;
554 if ( option
& LBER_BV_ALLOC
) {
555 bv
->bv_val
= (char *) ber_memalloc_x( bv
->bv_len
+ 1,
557 if ( bv
->bv_val
== NULL
) {
561 if ( bv
->bv_len
> 0 && (ber_len_t
) ber_read( ber
, bv
->bv_val
,
562 bv
->bv_len
) != bv
->bv_len
)
564 LBER_FREE( bv
->bv_val
);
569 bv
->bv_val
= ber
->ber_ptr
;
570 ber
->ber_ptr
+= bv
->bv_len
;
572 ber
->ber_tag
= *(unsigned char *)ber
->ber_ptr
;
573 if ( !( option
& LBER_BV_NOTERM
))
574 bv
->bv_val
[bv
->bv_len
] = '\0';
580 ber_get_stringa( BerElement
*ber
, char **buf
)
585 assert( buf
!= NULL
);
587 tag
= ber_get_stringbv( ber
, &bv
, LBER_BV_ALLOC
);
594 ber_get_stringa_null( BerElement
*ber
, char **buf
)
599 assert( buf
!= NULL
);
601 tag
= ber_get_stringbv_null( ber
, &bv
, LBER_BV_ALLOC
);
608 ber_get_stringal( BerElement
*ber
, struct berval
**bv
)
612 assert( ber
!= NULL
);
613 assert( bv
!= NULL
);
615 *bv
= (struct berval
*) ber_memalloc_x( sizeof(struct berval
),
621 tag
= ber_get_stringbv( ber
, *bv
, LBER_BV_ALLOC
);
622 if ( tag
== LBER_DEFAULT
) {
637 unsigned char unusedbits
;
639 assert( ber
!= NULL
);
640 assert( buf
!= NULL
);
641 assert( blen
!= NULL
);
643 assert( LBER_VALID( ber
) );
645 if ( (tag
= ber_skip_tag( ber
, &datalen
)) == LBER_DEFAULT
) {
651 *buf
= (char *) ber_memalloc_x( datalen
, ber
->ber_memctx
);
652 if ( *buf
== NULL
) {
656 if ( ber_read( ber
, (char *)&unusedbits
, 1 ) != 1 ) {
662 if ( (ber_len_t
) ber_read( ber
, *buf
, datalen
) != datalen
) {
667 ber
->ber_tag
= *(unsigned char *)ber
->ber_ptr
;
669 *blen
= datalen
* 8 - unusedbits
;
674 ber_get_null( BerElement
*ber
)
679 assert( ber
!= NULL
);
680 assert( LBER_VALID( ber
) );
682 if ( (tag
= ber_skip_tag( ber
, &len
)) == LBER_DEFAULT
) {
689 ber
->ber_tag
= *(unsigned char *)ber
->ber_ptr
;
702 assert( ber
!= NULL
);
703 assert( boolval
!= NULL
);
705 assert( LBER_VALID( ber
) );
707 rc
= ber_get_int( ber
, &longbool
);
719 assert( ber
!= NULL
);
720 assert( len
!= NULL
);
721 assert( last
!= NULL
);
723 /* skip the sequence header, use the len to mark where to stop */
724 if ( ber_skip_tag( ber
, len
) == LBER_DEFAULT
) {
728 ber
->ber_tag
= *(unsigned char *)ber
->ber_ptr
;
730 *last
= ber
->ber_ptr
+ *len
;
732 if ( *last
== ber
->ber_ptr
) {
736 return ber_peek_tag( ber
, len
);
743 LDAP_CONST
char *last
)
745 assert( ber
!= NULL
);
746 assert( len
!= NULL
);
747 assert( last
!= NULL
);
749 assert( LBER_VALID( ber
) );
751 if ( ber
->ber_ptr
>= last
) {
755 return ber_peek_tag( ber
, len
);
760 ber_scanf ( BerElement
*ber
,
761 LDAP_CONST
char *fmt
,
765 LDAP_CONST
char *fmt_reset
;
767 struct berval
**bvp
, *bval
;
776 assert( ber
!= NULL
);
777 assert( fmt
!= NULL
);
779 assert( LBER_VALID( ber
) );
783 if ( ber
->ber_debug
& (LDAP_DEBUG_TRACE
|LDAP_DEBUG_BER
)) {
784 ber_log_printf( LDAP_DEBUG_TRACE
, ber
->ber_debug
,
785 "ber_scanf fmt (%s) ber:\n", fmt
);
786 ber_log_dump( LDAP_DEBUG_BER
, ber
->ber_debug
, ber
, 1 );
789 for ( rc
= 0; *fmt
&& rc
!= LBER_DEFAULT
; fmt
++ ) {
790 /* When this is modified, remember to update
791 * the error-cleanup code below accordingly. */
793 case '!': { /* Hook */
794 BERDecodeCallback
*f
;
797 f
= va_arg( ap
, BERDecodeCallback
* );
798 p
= va_arg( ap
, void * );
800 rc
= (*f
)( ber
, p
, 0 );
803 case 'a': /* octet string - allocate storage as needed */
804 ss
= va_arg( ap
, char ** );
805 rc
= ber_get_stringa( ber
, ss
);
808 case 'A': /* octet string - allocate storage as needed,
809 * but return NULL if len == 0 */
810 ss
= va_arg( ap
, char ** );
811 rc
= ber_get_stringa_null( ber
, ss
);
814 case 'b': /* boolean */
815 i
= va_arg( ap
, ber_int_t
* );
816 rc
= ber_get_boolean( ber
, i
);
819 case 'B': /* bit string - allocate storage as needed */
820 ss
= va_arg( ap
, char ** );
821 l
= va_arg( ap
, ber_len_t
* ); /* for length, in bits */
822 rc
= ber_get_bitstringa( ber
, ss
, l
);
825 case 'e': /* enumerated */
827 i
= va_arg( ap
, ber_int_t
* );
828 rc
= ber_get_int( ber
, i
);
831 case 'l': /* length of next item */
832 l
= va_arg( ap
, ber_len_t
* );
833 rc
= ber_peek_tag( ber
, l
);
836 case 'm': /* octet string in berval, in-place */
837 bval
= va_arg( ap
, struct berval
* );
838 rc
= ber_get_stringbv( ber
, bval
, 0 );
841 case 'M': /* bvoffarray - must include address of
842 * a record len, and record offset.
843 * number of records will be returned thru
844 * len ptr on finish. parsed in-place.
847 bgbvr cookie
= { BvOff
};
849 cookie
.res
.ba
= va_arg( ap
, struct berval
** );
851 l
= va_arg( ap
, ber_len_t
* );
853 cookie
.off
= va_arg( ap
, ber_len_t
);
854 rc
= ber_get_stringbvl( &cookie
, l
);
859 rc
= ber_get_null( ber
);
862 case 'o': /* octet string in a supplied berval */
863 bval
= va_arg( ap
, struct berval
* );
864 rc
= ber_get_stringbv( ber
, bval
, LBER_BV_ALLOC
);
867 case 'O': /* octet string - allocate & include length */
868 bvp
= va_arg( ap
, struct berval
** );
869 rc
= ber_get_stringal( ber
, bvp
);
872 case 's': /* octet string - in a buffer */
873 s
= va_arg( ap
, char * );
874 l
= va_arg( ap
, ber_len_t
* );
875 rc
= ber_get_stringb( ber
, s
, l
);
878 case 't': /* tag of next item */
879 t
= va_arg( ap
, ber_tag_t
* );
880 *t
= rc
= ber_peek_tag( ber
, &len
);
883 case 'T': /* skip tag of next item */
884 t
= va_arg( ap
, ber_tag_t
* );
885 *t
= rc
= ber_skip_tag( ber
, &len
);
888 case 'v': /* sequence of strings */
890 bgbvr cookie
= { ChArray
};
892 cookie
.res
.c
= va_arg( ap
, char *** );
893 cookie
.alloc
= LBER_BV_ALLOC
;
894 rc
= ber_get_stringbvl( &cookie
, NULL
);
898 case 'V': /* sequence of strings + lengths */
900 bgbvr cookie
= { BvVec
};
902 cookie
.res
.bv
= va_arg( ap
, struct berval
*** );
903 cookie
.alloc
= LBER_BV_ALLOC
;
904 rc
= ber_get_stringbvl( &cookie
, NULL
);
908 case 'W': /* bvarray */
910 bgbvr cookie
= { BvArray
};
912 cookie
.res
.ba
= va_arg( ap
, struct berval
** );
913 cookie
.alloc
= LBER_BV_ALLOC
;
914 rc
= ber_get_stringbvl( &cookie
, NULL
);
918 case 'x': /* skip the next element - whatever it is */
919 if ( (rc
= ber_skip_tag( ber
, &len
)) == LBER_DEFAULT
)
922 ber
->ber_tag
= *(unsigned char *)ber
->ber_ptr
;
925 case '{': /* begin sequence */
926 case '[': /* begin set */
927 if ( *(fmt
+ 1) != 'v' && *(fmt
+ 1) != 'V'
928 && *(fmt
+ 1) != 'W' && *(fmt
+ 1) != 'M' )
929 rc
= ber_skip_tag( ber
, &len
);
932 case '}': /* end sequence */
933 case ']': /* end set */
937 if( ber
->ber_debug
) {
938 ber_log_printf( LDAP_DEBUG_ANY
, ber
->ber_debug
,
939 "ber_scanf: unknown fmt %c\n", *fmt
);
947 if ( rc
== LBER_DEFAULT
) {
949 * Error. Reclaim malloced memory that was given to the caller.
950 * Set allocated pointers to NULL, "data length" outvalues to 0.
954 for ( ; fmt_reset
< fmt
; fmt_reset
++ ) {
955 switch ( *fmt_reset
) {
956 case '!': { /* Hook */
957 BERDecodeCallback
*f
;
960 f
= va_arg( ap
, BERDecodeCallback
* );
961 p
= va_arg( ap
, void * );
963 (void) (*f
)( ber
, p
, 1 );
966 case 'a': /* octet string - allocate storage as needed */
968 ss
= va_arg( ap
, char ** );
975 case 'b': /* boolean */
976 case 'e': /* enumerated */
978 (void) va_arg( ap
, int * );
981 case 'l': /* length of next item */
982 (void) va_arg( ap
, ber_len_t
* );
985 case 'o': /* octet string in a supplied berval */
986 bval
= va_arg( ap
, struct berval
* );
987 if ( bval
->bv_val
!= NULL
) {
988 LBER_FREE( bval
->bv_val
);
994 case 'O': /* octet string - allocate & include length */
995 bvp
= va_arg( ap
, struct berval
** );
1002 case 's': /* octet string - in a buffer */
1003 (void) va_arg( ap
, char * );
1004 (void) va_arg( ap
, ber_len_t
* );
1007 case 't': /* tag of next item */
1008 case 'T': /* skip tag of next item */
1009 (void) va_arg( ap
, ber_tag_t
* );
1012 case 'B': /* bit string - allocate storage as needed */
1013 ss
= va_arg( ap
, char ** );
1018 *(va_arg( ap
, ber_len_t
* )) = 0; /* for length, in bits */
1021 case 'm': /* berval in-place */
1022 case 'M': /* BVoff array in-place */
1023 case 'n': /* null */
1024 case 'v': /* sequence of strings */
1025 case 'V': /* sequence of strings + lengths */
1026 case 'W': /* BerVarray */
1027 case 'x': /* skip the next element - whatever it is */
1028 case '{': /* begin sequence */
1029 case '[': /* begin set */
1030 case '}': /* end sequence */
1031 case ']': /* end set */
1035 /* format should be good */