provide some infrastructure for signed ints

This commit is contained in:
leitner
2002-03-14 17:26:06 +00:00
parent 750d4fd7ba
commit 2848136fc9
12 changed files with 92 additions and 29 deletions

View File

@@ -1,12 +1,13 @@
DEBUG=1
#DEBUG=1
all: t t1 t2 bindrequest tinyldap ldapclient ldapclient_str
all: t1 t2 bindrequest tinyldap ldapclient ldapclient_str # t
asn1.a: fmt_asn1intpayload.o fmt_asn1length.o fmt_asn1tag.o \
fmt_asn1int.o fmt_asn1string.o fmt_asn1transparent.o scan_asn1tag.o \
scan_asn1length.o scan_asn1int.o scan_asn1string.o scan_asn1INTEGER.o \
scan_asn1STRING.o scan_asn1SEQUENCE.o scan_asn1ENUMERATED.o \
scan_asn1BOOLEAN.o scan_asn1rawint.o scan_asn1SET.o
scan_asn1BOOLEAN.o scan_asn1rawint.o scan_asn1SET.o fmt_asn1sint.o \
fmt_asn1sintpayload.o
ldap.a: scan_ldapmessage.o fmt_ldapmessage.o fmt_ldapbindrequest.o \
scan_ldapbindrequest.o scan_ldapbindresponse.o scan_ldapresult.o \
@@ -20,10 +21,10 @@ ldif.a: ldif_parse.o ldap_match.o strduptab.o strstorage.o
DIET=diet -Os
CC=gcc
CFLAGS=-pipe -I. -Wall
CFLAGS=-pipe -I. -Wall -W
ifneq ($(DEBUG),)
DIET=diet
CFLAGS=-pipe -I. -Wall -g
CFLAGS=-pipe -I. -Wall -W -g
endif
%.o: %.c

35
asn1.h
View File

@@ -1,3 +1,6 @@
/* parser and formatter for ASN.1 DER encoding.
* The parser can read BER encoding, too. */
enum asn1_tagclass {
UNIVERSAL=(0<<6),
APPLICATION=(1<<6),
@@ -32,10 +35,19 @@ int fmt_asn1length(char* dest,unsigned long l);
* and length headers! */
int fmt_asn1intpayload(char* dest,unsigned long l);
/* write int in least amount of bytes, return number of bytes */
/* as used in ASN.1 INTEGER. This only does the payload, not the tag
* and length headers! */
int fmt_asn1sintpayload(char* dest,signed long l);
/* write int in least amount of bytes, return number of bytes */
/* as used in ASN.1 INTEGER or ENUMERATED. */
int fmt_asn1int(char* dest,enum asn1_tagclass tc,enum asn1_tagtype tt,enum asn1_tag tag,unsigned long l);
/* write int in least amount of bytes, return number of bytes */
/* as used in ASN.1 INTEGER or ENUMERATED. */
int fmt_asn1sint(char* dest,enum asn1_tagclass tc,enum asn1_tagtype tt,enum asn1_tag tag,signed long l);
/* write any data type that does not require transformation in the least
* amount of bytes, return number of bytes */
/* as used in ASN.1 OCTET STRING, SEQUENCE etc. */
@@ -66,19 +78,38 @@ int fmt_asn1string(char* dest,enum asn1_tagclass tc,enum asn1_tagtype tt,enum as
/* write ASN.1 SET */
#define fmt_asn1SET(dest,l) fmt_asn1transparent(dest,UNIVERSAL,CONSTRUCTED,SET_OF,l);
/* conventions for the parser routines:
* src points to the first byte to parse
* max points to the first byte behind the buffer
* the return value is the number of bytes parsed or 0 for parse error */
/* parse ASN.1 tag into a tag class, tag type and tag number */
int scan_asn1tag(const char* src,const char* max,
enum asn1_tagclass* tc,enum asn1_tagtype* tt, unsigned long* tag);
/* parse ASN.1 length */
int scan_asn1length(const char* src,const char* max,unsigned long* length);
/* parse ASN.1 integer with tag and length */
int scan_asn1int(const char* src,const char* max,
enum asn1_tagclass* tc,enum asn1_tagtype* tt, unsigned long* tag,
unsigned long* l);
long* l);
/* parse raw integer (payload after tag and length); internal helper */
int scan_asn1rawint(const char* src,const char* max,unsigned int len,long* i);
/* parse string with tag and length.
* Points s to the first byte in the string, and writes the length of
* the string to l. */
int scan_asn1string(const char* src,const char* max,
enum asn1_tagclass* tc,enum asn1_tagtype* tt,unsigned long* tag,
const char** s,unsigned long* l);
/* the following expect a specific universal type and return a parse
* error if the tag does not match that type */
int scan_asn1BOOLEAN(const char* src,const char* max,unsigned long* l);
int scan_asn1INTEGER(const char* src,const char* max,unsigned long* l);
int scan_asn1INTEGER(const char* src,const char* max,signed long* l);
int scan_asn1ENUMERATED(const char* src,const char* max,unsigned long* l);
int scan_asn1STRING(const char* src,const char* max,const char** s,unsigned long* l);
int scan_asn1SEQUENCE(const char* src,const char* max,unsigned long* len);

11
fmt_asn1sint.c Normal file
View File

@@ -0,0 +1,11 @@
#include <asn1.h>
int fmt_asn1sint(char* dest,enum asn1_tagclass tc,enum asn1_tagtype tt,enum asn1_tag tag,signed long l) {
int len,tmp;
/* first the tag */
if (!dest) return fmt_asn1tag(0,tc,tt,tag)+1+fmt_asn1intpayload(0,l);
len=fmt_asn1tag(dest,tc,tt,tag);
tmp=fmt_asn1sintpayload(dest+len+1,l);
if (fmt_asn1length(dest+len,tmp)!=1) return 0;
return len+tmp+1;
}

23
fmt_asn1sintpayload.c Normal file
View File

@@ -0,0 +1,23 @@
#include <asn1.h>
int fmt_asn1sintpayload(char* dest,signed long l) {
int needed=sizeof l;
int i;
signed long tmp=0x7f;
if (l>=0) return fmt_asn1intpayload(dest,l);
for (i=1; i<needed; ++i) {
/* assumes two's complement */
if ((l|tmp) == -1)
break;
tmp=(tmp<<8)|0xff;
}
if (dest) {
int j=i;
while (j) {
--j;
*dest=(l>>(j*8))&0xff;
++dest;
}
}
return i;
}

View File

@@ -43,7 +43,7 @@ int fmt_ldapsearchfilter(char* dest,struct Filter* f) {
l=fmt_ldapstring(nd,&f->ava.desc);
l+=fmt_asn1SEQUENCE(nd+l,tmp);
l+=fmt_ldapsubstring(nd+l,f->substrings);
sum+=l;
sum=l;
}
break;
case PRESENT:

View File

@@ -1,3 +1,4 @@
#include "byte.h"
#include "ldif.h"
/* behave like strcmp */

View File

@@ -1,6 +1,6 @@
#include "asn1.h"
int scan_asn1INTEGER(const char* src,const char* max,unsigned long* l) {
int scan_asn1INTEGER(const char* src,const char* max,signed long* l) {
int tmp;
long tag;
enum asn1_tagclass tc;

View File

@@ -1,20 +1,11 @@
#include "asn1.h"
static long int handleint(const unsigned char* c,int len) {
long l=0;
while (len) {
l=l*256+*c;
--len; ++c;
}
return l;
}
int scan_asn1int(const char* src,const char* max,enum asn1_tagclass* tc,enum asn1_tagtype* tt,unsigned long* tag,unsigned long* l) {
int scan_asn1int(const char* src,const char* max,enum asn1_tagclass* tc,enum asn1_tagtype* tt,unsigned long* tag,signed long* l) {
int len,tmp;
long tlen;
if (!(len=scan_asn1tag(src,max,tc,tt,tag))) return 0;
if (!(tmp=scan_asn1length(src+len,max,&tlen))) return 0;
len+=tmp;
*l=handleint(src+len,tlen);
if (!(scan_asn1rawint(src+len,max,tlen,l))) return 0;
return len+tlen;
}

View File

@@ -1,12 +1,16 @@
#include "asn1.h"
int scan_asn1rawint(const char* src,const char* max,unsigned int len,long* l) {
int i;
*l=0;
for (i=0; i<len; ++i) {
*l=*l*256+*src;
unsigned int i,j;
long m;
if (*src<0) m=-1; else m=0;
for (i=j=0; i<len; ++i,++j) {
if ((m==0 && *src==0) || (m==-1 && *src==-1)) --j;
m=(m<<8)|(unsigned char)*src;
++src;
if (src>max) return 0;
}
if (j>sizeof(long)) return 0;
*l=m;
return len;
}

View File

@@ -10,8 +10,7 @@ int scan_ldapbindrequest(const char* src,const char* max,
{
enum asn1_tagclass tc;
enum asn1_tagtype tt;
long method;
if (!(tmp=scan_asn1tag(src+res,max,&tc,&tt,&method))) return 0;
if (!(tmp=scan_asn1tag(src+res,max,&tc,&tt,method))) return 0;
if (tc!=PRIVATE || tt!=PRIMITIVE) return 0;
}
return res;

View File

@@ -34,7 +34,8 @@ int scan_ldapsearchfilter(const char* src,const char* max,struct Filter** f) {
enum asn1_tagclass tc;
enum asn1_tagtype tt;
unsigned long tag,len;
int res,tmp;
int res;
unsigned int tmp;
const char* nmax;
*f=0;
if (!(res=scan_asn1tag(src,max,&tc,&tt,&tag))) goto error;

5
t2.c
View File

@@ -87,7 +87,8 @@ int main(int argc,char* argv[]) {
// char* ldapsequence=mmap_read("req",&size);
char* ldapsequence=mmap_read(argc>1?argv[1]:"/tmp/ldap/127.000.000.001.00389-127.000.000.001.38433",&size);
long messageid, op, len;
int res,done=0;
int res;
unsigned long done=0;
while (done<size) {
printf("scan_ldapmessage: %d\n",res=scan_ldapmessage(ldapsequence+done,ldapsequence+size,&messageid,&op,&len));
if (!res) { puts("punt!"); break; }
@@ -151,7 +152,7 @@ int main(int argc,char* argv[]) {
case 2: printf("derefFindingBaseObj"); break;
case 3: printf("derefAlways"); break;
}
printf(", size limit %d, time limit %d\n",br.sizeLimit,br.timeLimit);
printf(", size limit %ld, time limit %ld\n",br.sizeLimit,br.timeLimit);
printfilter(br.filter); printf("\n");
}
printal(br.attributes);