add "generic" format string based encoder and decoder (scan_asn1generic,
fmt_asn1generic, see t10.c for example usage) add "generic" asn.1 dumper (in t10.c) fix some read off-by-one errors, minor cleanups add real OID support add bitstring support
This commit is contained in:
10
Makefile
10
Makefile
@@ -10,7 +10,9 @@ 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_asn1length.o scan_asn1int.o scan_asn1string.o scan_asn1INTEGER.o \
|
||||||
scan_asn1STRING.o scan_asn1SEQUENCE.o scan_asn1ENUMERATED.o \
|
scan_asn1STRING.o scan_asn1SEQUENCE.o scan_asn1ENUMERATED.o \
|
||||||
scan_asn1BOOLEAN.o scan_asn1rawint.o scan_asn1SET.o fmt_asn1sint.o \
|
scan_asn1BOOLEAN.o scan_asn1rawint.o scan_asn1SET.o fmt_asn1sint.o \
|
||||||
fmt_asn1sintpayload.o scan_asn1oid.o
|
fmt_asn1sintpayload.o scan_asn1oid.o scan_asn1BITSTRING.o \
|
||||||
|
scan_asn1tagint.o fmt_asn1tagint.o fmt_asn1OID.o scan_asn1generic.o \
|
||||||
|
fmt_asn1generic.o
|
||||||
|
|
||||||
ldap.a: scan_ldapmessage.o fmt_ldapmessage.o fmt_ldapbindrequest.o \
|
ldap.a: scan_ldapmessage.o fmt_ldapmessage.o fmt_ldapbindrequest.o \
|
||||||
scan_ldapbindrequest.o scan_ldapbindresponse.o scan_ldapresult.o \
|
scan_ldapbindrequest.o scan_ldapbindresponse.o scan_ldapresult.o \
|
||||||
@@ -111,6 +113,7 @@ fmt_asn1sint.o: fmt_asn1sint.c asn1.h
|
|||||||
fmt_asn1sintpayload.o: fmt_asn1sintpayload.c asn1.h
|
fmt_asn1sintpayload.o: fmt_asn1sintpayload.c asn1.h
|
||||||
fmt_asn1string.o: fmt_asn1string.c asn1.h
|
fmt_asn1string.o: fmt_asn1string.c asn1.h
|
||||||
fmt_asn1tag.o: fmt_asn1tag.c asn1.h
|
fmt_asn1tag.o: fmt_asn1tag.c asn1.h
|
||||||
|
fmt_asn1tagint.o: fmt_asn1tagint.c asn1.h
|
||||||
fmt_asn1transparent.o: fmt_asn1transparent.c asn1.h
|
fmt_asn1transparent.o: fmt_asn1transparent.c asn1.h
|
||||||
fmt_ldapadl.o: fmt_ldapadl.c asn1.h ldap.h
|
fmt_ldapadl.o: fmt_ldapadl.c asn1.h ldap.h
|
||||||
fmt_ldapava.o: fmt_ldapava.c asn1.h ldap.h
|
fmt_ldapava.o: fmt_ldapava.c asn1.h ldap.h
|
||||||
@@ -123,6 +126,8 @@ fmt_ldapsearchfilterstring.o: fmt_ldapsearchfilterstring.c ldap.h
|
|||||||
fmt_ldapsearchrequest.o: fmt_ldapsearchrequest.c asn1.h ldap.h
|
fmt_ldapsearchrequest.o: fmt_ldapsearchrequest.c asn1.h ldap.h
|
||||||
fmt_ldapsearchresultentry.o: fmt_ldapsearchresultentry.c asn1.h ldap.h
|
fmt_ldapsearchresultentry.o: fmt_ldapsearchresultentry.c asn1.h ldap.h
|
||||||
fmt_ldapstring.o: fmt_ldapstring.c asn1.h ldap.h
|
fmt_ldapstring.o: fmt_ldapstring.c asn1.h ldap.h
|
||||||
|
fmt_asn1OID.o: fmt_asn1OID.c asn1.h
|
||||||
|
fmt_asn1generic.o: fmt_asn1generic.c asn1.h
|
||||||
|
|
||||||
scan_asn1BOOLEAN.o: scan_asn1BOOLEAN.c asn1.h
|
scan_asn1BOOLEAN.o: scan_asn1BOOLEAN.c asn1.h
|
||||||
scan_asn1ENUMERATED.o: scan_asn1ENUMERATED.c asn1.h
|
scan_asn1ENUMERATED.o: scan_asn1ENUMERATED.c asn1.h
|
||||||
@@ -130,12 +135,14 @@ scan_asn1INTEGER.o: scan_asn1INTEGER.c asn1.h
|
|||||||
scan_asn1SEQUENCE.o: scan_asn1SEQUENCE.c asn1.h
|
scan_asn1SEQUENCE.o: scan_asn1SEQUENCE.c asn1.h
|
||||||
scan_asn1SET.o: scan_asn1SET.c asn1.h
|
scan_asn1SET.o: scan_asn1SET.c asn1.h
|
||||||
scan_asn1STRING.o: scan_asn1STRING.c asn1.h
|
scan_asn1STRING.o: scan_asn1STRING.c asn1.h
|
||||||
|
scan_asn1BITSTRING.o: scan_asn1BITSTRING.c asn1.h
|
||||||
scan_asn1int.o: scan_asn1int.c asn1.h
|
scan_asn1int.o: scan_asn1int.c asn1.h
|
||||||
scan_asn1length.o: scan_asn1length.c asn1.h
|
scan_asn1length.o: scan_asn1length.c asn1.h
|
||||||
scan_asn1oid.o: scan_asn1oid.c asn1.h
|
scan_asn1oid.o: scan_asn1oid.c asn1.h
|
||||||
scan_asn1rawint.o: scan_asn1rawint.c asn1.h
|
scan_asn1rawint.o: scan_asn1rawint.c asn1.h
|
||||||
scan_asn1string.o: scan_asn1string.c asn1.h
|
scan_asn1string.o: scan_asn1string.c asn1.h
|
||||||
scan_asn1tag.o: scan_asn1tag.c asn1.h
|
scan_asn1tag.o: scan_asn1tag.c asn1.h
|
||||||
|
scan_asn1tagint.o: scan_asn1tagint.c asn1.h
|
||||||
scan_ldapaddrequest.o: scan_ldapaddrequest.c asn1.h ldap.h
|
scan_ldapaddrequest.o: scan_ldapaddrequest.c asn1.h ldap.h
|
||||||
scan_ldapava.o: scan_ldapava.c asn1.h ldap.h
|
scan_ldapava.o: scan_ldapava.c asn1.h ldap.h
|
||||||
scan_ldapbindrequest.o: scan_ldapbindrequest.c asn1.h ldap.h
|
scan_ldapbindrequest.o: scan_ldapbindrequest.c asn1.h ldap.h
|
||||||
@@ -148,5 +155,6 @@ scan_ldapsearchfilterstring.o: scan_ldapsearchfilterstring.c ldap.h
|
|||||||
scan_ldapsearchrequest.o: scan_ldapsearchrequest.c asn1.h ldap.h
|
scan_ldapsearchrequest.o: scan_ldapsearchrequest.c asn1.h ldap.h
|
||||||
scan_ldapsearchresultentry.o: scan_ldapsearchresultentry.c asn1.h ldap.h
|
scan_ldapsearchresultentry.o: scan_ldapsearchresultentry.c asn1.h ldap.h
|
||||||
scan_ldapstring.o: scan_ldapstring.c asn1.h ldap.h
|
scan_ldapstring.o: scan_ldapstring.c asn1.h ldap.h
|
||||||
|
scan_asn1generic.o: scan_asn1generic.c asn1.h
|
||||||
|
|
||||||
ldap_match_sre.o: ldap_match_sre.c ldap.h
|
ldap_match_sre.o: ldap_match_sre.c ldap.h
|
||||||
|
|||||||
6
acl.c
6
acl.c
@@ -1,6 +1,7 @@
|
|||||||
#define _FILE_OFFSET_BITS 64
|
#define _FILE_OFFSET_BITS 64
|
||||||
#define MAIN
|
#define MAIN
|
||||||
|
|
||||||
|
#include "ldap.h"
|
||||||
#include <buffer.h>
|
#include <buffer.h>
|
||||||
#include <stralloc.h>
|
#include <stralloc.h>
|
||||||
#include <str.h>
|
#include <str.h>
|
||||||
@@ -11,7 +12,6 @@
|
|||||||
#include <byte.h>
|
#include <byte.h>
|
||||||
#include <mmap.h>
|
#include <mmap.h>
|
||||||
#include <case.h>
|
#include <case.h>
|
||||||
#include <ldap.h>
|
|
||||||
#include <uint16.h>
|
#include <uint16.h>
|
||||||
#include <uint32.h>
|
#include <uint32.h>
|
||||||
#include <open.h>
|
#include <open.h>
|
||||||
@@ -275,7 +275,7 @@ int marshalfilter(stralloc* x,struct assertion* a) {
|
|||||||
|
|
||||||
int marshal(char* map,size_t filelen,const char* filename) {
|
int marshal(char* map,size_t filelen,const char* filename) {
|
||||||
size_t filters,acls,i,j,k;
|
size_t filters,acls,i,j,k;
|
||||||
size_t filter_offset,acl_offset;
|
size_t filter_offset; //,acl_offset;
|
||||||
struct acl* a;
|
struct acl* a;
|
||||||
uint32* F,* A;
|
uint32* F,* A;
|
||||||
uint32 attribute_count;
|
uint32 attribute_count;
|
||||||
@@ -396,7 +396,7 @@ nomem:
|
|||||||
|
|
||||||
A=malloc(sizeof(*A)*acls);
|
A=malloc(sizeof(*A)*acls);
|
||||||
if (!A) goto nomem;
|
if (!A) goto nomem;
|
||||||
acl_offset=F[i]+(acls+1)*sizeof(*A);
|
// acl_offset=F[i]+(acls+1)*sizeof(*A);
|
||||||
|
|
||||||
i=0;
|
i=0;
|
||||||
for (a=root; a; a=a->next) {
|
for (a=root; a; a=a->next) {
|
||||||
|
|||||||
28
asn1.h
28
asn1.h
@@ -1,3 +1,6 @@
|
|||||||
|
#ifndef ASN1_H
|
||||||
|
#define ASN1_H
|
||||||
|
|
||||||
/* parser and formatter for ASN.1 DER encoding.
|
/* parser and formatter for ASN.1 DER encoding.
|
||||||
* The parser can read BER encoding, too. */
|
* The parser can read BER encoding, too. */
|
||||||
|
|
||||||
@@ -18,12 +21,18 @@ enum asn1_tagtype {
|
|||||||
enum asn1_tag {
|
enum asn1_tag {
|
||||||
BOOLEAN=1,
|
BOOLEAN=1,
|
||||||
INTEGER=2,
|
INTEGER=2,
|
||||||
|
BIT_STRING=3,
|
||||||
OCTET_STRING=4,
|
OCTET_STRING=4,
|
||||||
|
OBJECT_IDENTIFIER=6,
|
||||||
ENUMERATED=10,
|
ENUMERATED=10,
|
||||||
SEQUENCE_OF=16,
|
SEQUENCE_OF=16,
|
||||||
SET_OF=17,
|
SET_OF=17,
|
||||||
|
UTCTIME=23
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* write variable length integer in the encoding used in tag and oid */
|
||||||
|
size_t fmt_asn1tagint(char* dest,unsigned long val);
|
||||||
|
|
||||||
/* write int in least amount of bytes, return number of bytes */
|
/* write int in least amount of bytes, return number of bytes */
|
||||||
/* as used in ASN.1 tag */
|
/* as used in ASN.1 tag */
|
||||||
size_t fmt_asn1tag(char* dest,enum asn1_tagclass tc,enum asn1_tagtype tt,
|
size_t fmt_asn1tag(char* dest,enum asn1_tagclass tc,enum asn1_tagtype tt,
|
||||||
@@ -85,12 +94,17 @@ size_t fmt_asn1string(char* dest,enum asn1_tagclass tc,enum asn1_tagtype tt,
|
|||||||
/* write ASN.1 SET */
|
/* write ASN.1 SET */
|
||||||
#define fmt_asn1SET(dest,l) fmt_asn1transparent(dest,UNIVERSAL,CONSTRUCTED,SET_OF,l)
|
#define fmt_asn1SET(dest,l) fmt_asn1transparent(dest,UNIVERSAL,CONSTRUCTED,SET_OF,l)
|
||||||
|
|
||||||
|
size_t fmt_asn1OID(char* dest,const unsigned long* array,unsigned long len);
|
||||||
|
|
||||||
|
|
||||||
/* conventions for the parser routines:
|
/* conventions for the parser routines:
|
||||||
* src points to the first byte to parse
|
* src points to the first byte to parse
|
||||||
* max points to the first byte behind the buffer
|
* max points to the first byte behind the buffer
|
||||||
* the return value is the number of bytes parsed or 0 for parse error */
|
* the return value is the number of bytes parsed or 0 for parse error */
|
||||||
|
|
||||||
|
/* parse ASN.1 variable length integer as used in tag and oid */
|
||||||
|
size_t scan_asn1tagint(const char* src,const char* max,unsigned long* val);
|
||||||
|
|
||||||
/* parse ASN.1 tag into a tag class, tag type and tag number */
|
/* parse ASN.1 tag into a tag class, tag type and tag number */
|
||||||
size_t scan_asn1tag(const char* src,const char* max,
|
size_t scan_asn1tag(const char* src,const char* max,
|
||||||
enum asn1_tagclass* tc,enum asn1_tagtype* tt, unsigned long* tag);
|
enum asn1_tagclass* tc,enum asn1_tagtype* tt, unsigned long* tag);
|
||||||
@@ -119,5 +133,19 @@ size_t scan_asn1BOOLEAN(const char* src,const char* max,unsigned long* l);
|
|||||||
size_t scan_asn1INTEGER(const char* src,const char* max,signed long* l);
|
size_t scan_asn1INTEGER(const char* src,const char* max,signed long* l);
|
||||||
size_t scan_asn1ENUMERATED(const char* src,const char* max,unsigned long* l);
|
size_t scan_asn1ENUMERATED(const char* src,const char* max,unsigned long* l);
|
||||||
size_t scan_asn1STRING(const char* src,const char* max,const char** s,size_t* l);
|
size_t scan_asn1STRING(const char* src,const char* max,const char** s,size_t* l);
|
||||||
|
size_t scan_asn1BITSTRING(const char* src,const char* max,const char** s,size_t* l);
|
||||||
size_t scan_asn1SEQUENCE(const char* src,const char* max,size_t* len);
|
size_t scan_asn1SEQUENCE(const char* src,const char* max,size_t* len);
|
||||||
size_t scan_asn1SET(const char* src,const char* max,size_t* len);
|
size_t scan_asn1SET(const char* src,const char* max,size_t* len);
|
||||||
|
|
||||||
|
/* scan an ASN.1 OID and put the numbers into array.
|
||||||
|
* Return numbers of bytes parsed or 0 on error.
|
||||||
|
* Put at most arraylen longs into array; if the OID is longer, or if array is NULL, return real number in arraylen and return 0
|
||||||
|
* If 0 is returned and arraylen is also 0, there was a parse error */
|
||||||
|
size_t scan_asn1oid(const char* src,const char* max,unsigned long* array,unsigned long* arraylen);
|
||||||
|
|
||||||
|
struct string {
|
||||||
|
size_t l;
|
||||||
|
const char* s;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|||||||
2
auth.c
2
auth.c
@@ -1,3 +1,4 @@
|
|||||||
|
#define _XOPEN_SOURCE
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#ifdef __dietlibc__
|
#ifdef __dietlibc__
|
||||||
#include <md5.h>
|
#include <md5.h>
|
||||||
@@ -7,7 +8,6 @@
|
|||||||
#define MD5Update MD5_Update
|
#define MD5Update MD5_Update
|
||||||
#define MD5Final MD5_Final
|
#define MD5Final MD5_Final
|
||||||
#endif
|
#endif
|
||||||
#define _XOPEN_SOURCE
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <alloca.h>
|
#include <alloca.h>
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ int main(int argc,char* argv[]) {
|
|||||||
if (!map) {
|
if (!map) {
|
||||||
buffer_puts(buffer_2,"could not open `");
|
buffer_puts(buffer_2,"could not open `");
|
||||||
buffer_puts(buffer_2,fn);
|
buffer_puts(buffer_2,fn);
|
||||||
buffer_puts(buffer_2,"´: ");
|
buffer_puts(buffer_2,"': ");
|
||||||
buffer_puterror(buffer_2);
|
buffer_puterror(buffer_2);
|
||||||
buffer_putnlflush(buffer_2);
|
buffer_putnlflush(buffer_2);
|
||||||
exit(1);
|
exit(1);
|
||||||
|
|||||||
16
fmt_asn1OID.c
Normal file
16
fmt_asn1OID.c
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
#include "asn1.h"
|
||||||
|
|
||||||
|
size_t fmt_asn1OID(char* dest,const unsigned long* array,unsigned long len) {
|
||||||
|
size_t i,l,l2;
|
||||||
|
if (len<2) return 0;
|
||||||
|
for (l=1,i=2; i<len; ++i) {
|
||||||
|
l+=fmt_asn1tagint(dest,array[i]);
|
||||||
|
}
|
||||||
|
l2=fmt_asn1transparent(dest,UNIVERSAL,PRIMITIVE,OBJECT_IDENTIFIER,l);
|
||||||
|
if (!dest) return l+l2;
|
||||||
|
dest[l2]=array[0]*40+array[1];
|
||||||
|
dest+=l2+1;
|
||||||
|
for (i=2; i<len; ++i)
|
||||||
|
dest+=fmt_asn1tagint(dest,array[i]);
|
||||||
|
return l+l2;
|
||||||
|
}
|
||||||
76
fmt_asn1generic.c
Normal file
76
fmt_asn1generic.c
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
#include <stdarg.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "asn1.h"
|
||||||
|
|
||||||
|
size_t fmt_asn1generic(char* dest,const char* fmt,...) {
|
||||||
|
size_t containerstack[100];
|
||||||
|
size_t curinstack=0;
|
||||||
|
va_list args;
|
||||||
|
va_start(args,fmt);
|
||||||
|
unsigned long* application=0;
|
||||||
|
struct string* s;
|
||||||
|
struct string S;
|
||||||
|
size_t curlen=0;
|
||||||
|
size_t cursor=0;
|
||||||
|
size_t seqlen;
|
||||||
|
unsigned long appstore;
|
||||||
|
while (*fmt) {
|
||||||
|
char* realdest=dest?dest+cursor:NULL;
|
||||||
|
switch (*fmt) {
|
||||||
|
case 'a': // make next tag use APPLICATION with this tag
|
||||||
|
appstore=va_arg(args,unsigned long);
|
||||||
|
application=&appstore;
|
||||||
|
break;
|
||||||
|
case 'i': // send integer
|
||||||
|
{
|
||||||
|
unsigned long i=va_arg(args,unsigned long);
|
||||||
|
if (application)
|
||||||
|
curlen=fmt_asn1int(realdest,APPLICATION,PRIMITIVE,*application,i);
|
||||||
|
else
|
||||||
|
curlen=fmt_asn1int(realdest,UNIVERSAL,PRIMITIVE,INTEGER,i);
|
||||||
|
application=NULL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'S': // send OCTET_STRING, using struct string* as arg
|
||||||
|
s=va_arg(args,struct string*);
|
||||||
|
copystring:
|
||||||
|
if (application)
|
||||||
|
curlen=fmt_asn1string(realdest,APPLICATION,PRIMITIVE,*application,s->s,s->l);
|
||||||
|
else
|
||||||
|
curlen=fmt_asn1string(realdest,UNIVERSAL,PRIMITIVE,OCTET_STRING,s->s,s->l);
|
||||||
|
application=NULL;
|
||||||
|
break;
|
||||||
|
case 's': // send OCTET_STRING, using const char* with strlen() as arg
|
||||||
|
S.s=va_arg(args,const char*);
|
||||||
|
S.l=strlen(S.s);
|
||||||
|
s=&S;
|
||||||
|
goto copystring;
|
||||||
|
case '{': // start SEQUENCE
|
||||||
|
if (application)
|
||||||
|
curlen=fmt_asn1tag(realdest,APPLICATION,CONSTRUCTED,*application);
|
||||||
|
else
|
||||||
|
curlen=fmt_asn1tag(realdest,UNIVERSAL,CONSTRUCTED,SEQUENCE_OF);
|
||||||
|
containerstack[curinstack++]=cursor+curlen;
|
||||||
|
application=NULL;
|
||||||
|
break;
|
||||||
|
case '}': // end of SEQUENCE
|
||||||
|
/* we just wrote the tag and the sequence. Now that we wrote the
|
||||||
|
* sequence, we know the length it took, and we need to move the
|
||||||
|
* sequence data backwards to make room to write the ASN.1 length */
|
||||||
|
{
|
||||||
|
char* anfang;
|
||||||
|
if (!curinstack) return 0;
|
||||||
|
anfang=dest+containerstack[--curinstack];
|
||||||
|
seqlen=dest+cursor-anfang;
|
||||||
|
curlen=fmt_asn1length(NULL,seqlen);
|
||||||
|
if (!dest) break;
|
||||||
|
memmove(anfang+curlen,anfang,seqlen);
|
||||||
|
fmt_asn1length(anfang,seqlen);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cursor+=curlen;
|
||||||
|
++fmt;
|
||||||
|
}
|
||||||
|
return cursor;
|
||||||
|
}
|
||||||
@@ -4,22 +4,12 @@
|
|||||||
/* as used in ASN.1 tags */
|
/* as used in ASN.1 tags */
|
||||||
size_t fmt_asn1tag(char* dest,enum asn1_tagclass tc,enum asn1_tagtype tt,unsigned long l) {
|
size_t fmt_asn1tag(char* dest,enum asn1_tagclass tc,enum asn1_tagtype tt,unsigned long l) {
|
||||||
/* encoding is either l%128 or (0x1f,...) */
|
/* encoding is either l%128 or (0x1f,...) */
|
||||||
size_t needed=((sizeof l)*7)/8,i;
|
|
||||||
if (l<0x1f) {
|
if (l<0x1f) {
|
||||||
if (dest) *dest=(int)tc+(int)tt+(l&0x1f);
|
if (dest) *dest=(int)tc+(int)tt+(l&0x1f);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
for (i=1; i<needed; ++i)
|
|
||||||
if (!(l>>(i*7)))
|
|
||||||
break;
|
|
||||||
if (dest) {
|
if (dest) {
|
||||||
size_t j=i;
|
|
||||||
*dest=(int)tc+(int)tt+0x1f; ++dest;
|
*dest=(int)tc+(int)tt+0x1f; ++dest;
|
||||||
while (j) {
|
|
||||||
--j;
|
|
||||||
*dest=((l>>(j*7))&0x7f) + (j?0x80:0);
|
|
||||||
++dest;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return i+1;
|
return fmt_asn1tagint(dest,l)+1;
|
||||||
}
|
}
|
||||||
|
|||||||
17
fmt_asn1tagint.c
Normal file
17
fmt_asn1tagint.c
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
#include "asn1.h"
|
||||||
|
|
||||||
|
size_t fmt_asn1tagint(char* dest,unsigned long l) {
|
||||||
|
size_t needed=((sizeof l)*7)/8,i;
|
||||||
|
for (i=1; i<needed; ++i)
|
||||||
|
if (!(l>>(i*7)))
|
||||||
|
break;
|
||||||
|
if (dest) {
|
||||||
|
size_t j=i;
|
||||||
|
while (j) {
|
||||||
|
--j;
|
||||||
|
*dest=((l>>(j*7))&0x7f) + (j?0x80:0);
|
||||||
|
++dest;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return i;
|
||||||
|
}
|
||||||
@@ -1,4 +1,3 @@
|
|||||||
#include "asn1.h"
|
|
||||||
#include "ldap.h"
|
#include "ldap.h"
|
||||||
|
|
||||||
static size_t doit(char* dest,struct AttributeDescriptionList* adl,int seq) {
|
static size_t doit(char* dest,struct AttributeDescriptionList* adl,int seq) {
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
#include "asn1.h"
|
|
||||||
#include "ldap.h"
|
#include "ldap.h"
|
||||||
|
|
||||||
size_t fmt_ldapava(char* dest,struct AttributeValueAssertion* a) {
|
size_t fmt_ldapava(char* dest,struct AttributeValueAssertion* a) {
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "asn1.h"
|
|
||||||
#include "ldap.h"
|
#include "ldap.h"
|
||||||
#include "str.h"
|
#include "str.h"
|
||||||
#include "rangecheck.h"
|
#include "rangecheck.h"
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
#include "asn1.h"
|
|
||||||
#include "ldap.h"
|
#include "ldap.h"
|
||||||
|
|
||||||
size_t fmt_ldapmessage(char* dest,long messageid,long op,size_t len) {
|
size_t fmt_ldapmessage(char* dest,long messageid,long op,size_t len) {
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
#include "asn1.h"
|
|
||||||
#include "ldap.h"
|
#include "ldap.h"
|
||||||
|
|
||||||
size_t fmt_ldappal(char* dest,struct PartialAttributeList* pal) {
|
size_t fmt_ldappal(char* dest,struct PartialAttributeList* pal) {
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
#include "asn1.h"
|
|
||||||
#include "ldap.h"
|
#include "ldap.h"
|
||||||
#include "str.h"
|
#include "str.h"
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
#include <byte.h>
|
#include <byte.h>
|
||||||
#include "asn1.h"
|
|
||||||
#include "ldap.h"
|
#include "ldap.h"
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
@@ -51,7 +50,7 @@ size_t fmt_ldapsearchfilter(char* dest,struct Filter* f) {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case PRESENT:
|
case PRESENT:
|
||||||
return fmt_asn1string(dest,PRIVATE,PRIMITIVE,f->type,f->ava.desc.s,f->ava.desc.l);
|
return fmt_asn1string(dest,PRIVATE,PRIMITIVE,(enum asn1_tag)f->type,f->ava.desc.s,f->ava.desc.l);
|
||||||
break;
|
break;
|
||||||
default: return 0;
|
default: return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
#include "asn1.h"
|
|
||||||
#include "ldap.h"
|
#include "ldap.h"
|
||||||
|
|
||||||
size_t fmt_ldapsearchrequest(char* dest,struct SearchRequest* sr) {
|
size_t fmt_ldapsearchrequest(char* dest,struct SearchRequest* sr) {
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
#include "asn1.h"
|
|
||||||
#include "ldap.h"
|
#include "ldap.h"
|
||||||
|
|
||||||
size_t fmt_ldapsearchresultentry(char* dest,struct SearchResultEntry* sre) {
|
size_t fmt_ldapsearchresultentry(char* dest,struct SearchResultEntry* sre) {
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
#include "asn1.h"
|
|
||||||
#include "ldap.h"
|
#include "ldap.h"
|
||||||
|
|
||||||
size_t fmt_ldapstring(char* dest,struct string* s) {
|
size_t fmt_ldapstring(char* dest,struct string* s) {
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include "asn1.h"
|
|
||||||
#include "ldap.h"
|
#include "ldap.h"
|
||||||
|
|
||||||
void free_ldapsearchfilter(struct Filter* f) {
|
void free_ldapsearchfilter(struct Filter* f) {
|
||||||
|
|||||||
6
ldap.h
6
ldap.h
@@ -1,14 +1,10 @@
|
|||||||
#ifndef _LDAP_H
|
#ifndef _LDAP_H
|
||||||
#define _LDAP_H
|
#define _LDAP_H
|
||||||
|
|
||||||
|
#include "asn1.h"
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
|
|
||||||
struct string {
|
|
||||||
size_t l;
|
|
||||||
const char* s;
|
|
||||||
};
|
|
||||||
|
|
||||||
int matchstring(struct string* s,const char* c);
|
int matchstring(struct string* s,const char* c);
|
||||||
int matchcasestring(struct string* s,const char* c);
|
int matchcasestring(struct string* s,const char* c);
|
||||||
int matchprefix(struct string* s,const char* c);
|
int matchprefix(struct string* s,const char* c);
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
#include "ldap.h"
|
|
||||||
#include "ldif.h"
|
#include "ldif.h"
|
||||||
#include "byte.h"
|
#include "byte.h"
|
||||||
#include "str.h"
|
#include "str.h"
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "byte.h"
|
#include "byte.h"
|
||||||
#include "buffer.h"
|
#include "buffer.h"
|
||||||
#include "asn1.h"
|
|
||||||
#include "ldap.h"
|
#include "ldap.h"
|
||||||
#include "socket.h"
|
#include "socket.h"
|
||||||
#include "ip4.h"
|
#include "ip4.h"
|
||||||
@@ -51,7 +50,7 @@ static int ldapbind(int sock) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc,char* argv[]) {
|
int main(int argc,char* argv[]) {
|
||||||
int sock;
|
int sock=0;
|
||||||
char buf[BUFSIZE];
|
char buf[BUFSIZE];
|
||||||
int len=0;
|
int len=0;
|
||||||
char* me;
|
char* me;
|
||||||
|
|||||||
@@ -3,7 +3,6 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "byte.h"
|
#include "byte.h"
|
||||||
#include "buffer.h"
|
#include "buffer.h"
|
||||||
#include "asn1.h"
|
|
||||||
#include "ldap.h"
|
#include "ldap.h"
|
||||||
#include "socket.h"
|
#include "socket.h"
|
||||||
#include "ip4.h"
|
#include "ip4.h"
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "byte.h"
|
#include "byte.h"
|
||||||
#include "buffer.h"
|
#include "buffer.h"
|
||||||
#include "asn1.h"
|
|
||||||
#include "ldap.h"
|
#include "ldap.h"
|
||||||
#include "socket.h"
|
#include "socket.h"
|
||||||
#include "ip4.h"
|
#include "ip4.h"
|
||||||
|
|||||||
3
ldif.h
3
ldif.h
@@ -1,7 +1,8 @@
|
|||||||
#define _FILE_OFFSET_BITS 64
|
#define _FILE_OFFSET_BITS 64
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include <ldap.h>
|
#include "asn1.h"
|
||||||
|
#include "ldap.h"
|
||||||
|
|
||||||
/* how many attributes do we allow per record? */
|
/* how many attributes do we allow per record? */
|
||||||
#define ATTRIBS 100
|
#define ATTRIBS 100
|
||||||
|
|||||||
4
parse.c
4
parse.c
@@ -144,7 +144,7 @@ int main(int argc,char* argv[]) {
|
|||||||
char* destname=argc<3?"data":argv[2];
|
char* destname=argc<3?"data":argv[2];
|
||||||
char* tempname;
|
char* tempname;
|
||||||
unsigned long size_of_string_table,indices_offset;
|
unsigned long size_of_string_table,indices_offset;
|
||||||
long offset_stringtable;
|
// long offset_stringtable;
|
||||||
char* map;
|
char* map;
|
||||||
uint32 attrofs,classofs;
|
uint32 attrofs,classofs;
|
||||||
|
|
||||||
@@ -301,7 +301,7 @@ writeerror:
|
|||||||
uint32_pack(map+4*4,size_of_string_table); /* size_of_string_table */
|
uint32_pack(map+4*4,size_of_string_table); /* size_of_string_table */
|
||||||
|
|
||||||
// size_of_string_table=stringtable.used+classes.strings.used+attributes.strings.used;
|
// size_of_string_table=stringtable.used+classes.strings.used+attributes.strings.used;
|
||||||
offset_stringtable=5*4;
|
// offset_stringtable=5*4;
|
||||||
offset_classes=outofs;
|
offset_classes=outofs;
|
||||||
|
|
||||||
munmap(map,5*4);
|
munmap(map,5*4);
|
||||||
|
|||||||
27
scan_asn1BITSTRING.c
Normal file
27
scan_asn1BITSTRING.c
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
#include "asn1.h"
|
||||||
|
|
||||||
|
size_t scan_asn1BITSTRING(const char* src,const char* max,const char** s,size_t* l) {
|
||||||
|
size_t tmp;
|
||||||
|
unsigned long tag;
|
||||||
|
enum asn1_tagclass tc;
|
||||||
|
enum asn1_tagtype tt;
|
||||||
|
if ((tmp=scan_asn1string(src,max,&tc,&tt,&tag,s,l)))
|
||||||
|
if (tc==UNIVERSAL && tt==PRIMITIVE && tag==BIT_STRING) {
|
||||||
|
unsigned char lastbyte;
|
||||||
|
if (*l==0 || /* length must be at least 1 because for bit strings, the first octet contains the number of unused bits in the last octet */
|
||||||
|
(unsigned char)(**s)>7) /* the number of unused bits in the last octet must not be negative and can be at most 7 */
|
||||||
|
return 0;
|
||||||
|
/* these are DER checks */
|
||||||
|
/* can't have unused bits if the length is 0 */
|
||||||
|
if (*l==1 && **s)
|
||||||
|
return 0;
|
||||||
|
/* now check if the unused bits are 0 */
|
||||||
|
lastbyte=(*s)[*l+1];
|
||||||
|
if (lastbyte & (0xff >> (8-**s)))
|
||||||
|
return 0;
|
||||||
|
*l=*l*8-(unsigned char)(**s);
|
||||||
|
++*s;
|
||||||
|
return tmp;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
107
scan_asn1generic.c
Normal file
107
scan_asn1generic.c
Normal file
@@ -0,0 +1,107 @@
|
|||||||
|
#include <stdarg.h>
|
||||||
|
#include "asn1.h"
|
||||||
|
|
||||||
|
size_t scan_asn1generic(const char* src,const char* max,const char* fmt,...) {
|
||||||
|
size_t curlen,seqlen;
|
||||||
|
const char* maxstack[100];
|
||||||
|
size_t curmax=0;
|
||||||
|
va_list args;
|
||||||
|
int optional=0;
|
||||||
|
unsigned long* application=NULL;
|
||||||
|
unsigned long tag;
|
||||||
|
enum asn1_tagclass tc;
|
||||||
|
enum asn1_tagtype tt;
|
||||||
|
const char* orig=src;
|
||||||
|
va_start(args,fmt);
|
||||||
|
maxstack[0]=max;
|
||||||
|
while (*fmt) {
|
||||||
|
switch (*fmt) {
|
||||||
|
case '?': // ? = rest is optional (until end of sequence)
|
||||||
|
optional=1;
|
||||||
|
break;
|
||||||
|
case 'i': // i = INTEGER
|
||||||
|
{
|
||||||
|
long* dest=va_arg(args,long*);
|
||||||
|
*dest=0;
|
||||||
|
curlen=scan_asn1int(src,maxstack[curmax],&tc,&tt,&tag,dest);
|
||||||
|
if (application) {
|
||||||
|
if (tc!=APPLICATION) return 0;
|
||||||
|
*application=tag;
|
||||||
|
} else {
|
||||||
|
if (tc!=UNIVERSAL || tt!=PRIMITIVE || tag!=INTEGER)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (!curlen) { if (optional) break; else return 0; }
|
||||||
|
src+=curlen;
|
||||||
|
application=0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 's': // s = STRING
|
||||||
|
{
|
||||||
|
struct string* dest=va_arg(args,struct string*);
|
||||||
|
dest->l=0;
|
||||||
|
dest->s=0;
|
||||||
|
curlen=scan_asn1string(src,maxstack[curmax],&tc,&tt,&tag,&dest->s,&dest->l);
|
||||||
|
if (!curlen) { if (optional) break; else return 0; }
|
||||||
|
if (application) {
|
||||||
|
if (tc!=APPLICATION) return 0;
|
||||||
|
*application=tag;
|
||||||
|
} else {
|
||||||
|
if (tc!=UNIVERSAL || tt!=PRIMITIVE || tag!=OCTET_STRING)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
src+=curlen;
|
||||||
|
application=0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'a': // next tag class is APPLICATION instead of UNIVERSAL; write tag to unsigned long*
|
||||||
|
{
|
||||||
|
application=va_arg(args,unsigned long*);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case '{': // { = SEQUENCE
|
||||||
|
{
|
||||||
|
curlen=scan_asn1tag(src,maxstack[curmax],&tc,&tt,&tag);
|
||||||
|
if (!curlen) { if (optional) break; else return 0; }
|
||||||
|
if (application) {
|
||||||
|
if (tc!=APPLICATION) return 0;
|
||||||
|
*application=tag;
|
||||||
|
} else {
|
||||||
|
if (tc!=UNIVERSAL || tt!=CONSTRUCTED || tag!=SEQUENCE_OF)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
src+=curlen;
|
||||||
|
curlen=scan_asn1length(src,maxstack[curmax],&seqlen);
|
||||||
|
if (!curlen) return 0;
|
||||||
|
if (curmax>99) return 0;
|
||||||
|
maxstack[++curmax]=src+curlen+seqlen;
|
||||||
|
src+=curlen;
|
||||||
|
application=0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case '!': // save current max-src into size_t
|
||||||
|
// useful for ldap, where you have an application sequence
|
||||||
|
// and the tag defines which encoding you have inside the
|
||||||
|
// sequence, so you can't put it in the format string.
|
||||||
|
// you still need to know the length so you can call this function
|
||||||
|
// again on the rest of the data.
|
||||||
|
{
|
||||||
|
size_t* dest=va_arg(args,size_t*);
|
||||||
|
*dest=maxstack[curmax]-src;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case '}': // } = end of SEQUENCE
|
||||||
|
{
|
||||||
|
optional=0;
|
||||||
|
if (curmax==0) return 0;
|
||||||
|
--curmax;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
++fmt;
|
||||||
|
}
|
||||||
|
va_end(args);
|
||||||
|
return src-orig;
|
||||||
|
}
|
||||||
@@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
size_t scan_asn1length(const char* src,const char* max,size_t* length) {
|
size_t scan_asn1length(const char* src,const char* max,size_t* length) {
|
||||||
const char* orig=src;
|
const char* orig=src;
|
||||||
if (src>max) return 0;
|
if (src>=max) return 0;
|
||||||
/* If the highest bit of the first byte is clear, the byte is the length.
|
/* If the highest bit of the first byte is clear, the byte is the length.
|
||||||
* Otherwise the next n bytes are the length (n being the lower 7 bits) */
|
* Otherwise the next n bytes are the length (n being the lower 7 bits) */
|
||||||
if (*src&0x80) {
|
if (*src&0x80) {
|
||||||
|
|||||||
@@ -1,49 +1,49 @@
|
|||||||
#include "asn1.h"
|
#include "asn1.h"
|
||||||
|
|
||||||
size_t scan_asn1oid(const char* src,const char* max) {
|
size_t scan_asn1oid(const char* src,const char* max,unsigned long* array,unsigned long* arraylen) {
|
||||||
size_t res,tmp,tlen;
|
const char* orig=src;
|
||||||
unsigned long tag;
|
size_t res,tlen,cur=0,al;
|
||||||
|
unsigned long tag,tmp;
|
||||||
enum asn1_tagclass tc;
|
enum asn1_tagclass tc;
|
||||||
enum asn1_tagtype tt;
|
enum asn1_tagtype tt;
|
||||||
if (!(res=scan_asn1tag(src,max,&tc,&tt,&tag))) goto error;
|
if (!arraylen) return 0;
|
||||||
if (!(tmp=scan_asn1length(src+res,max,&tlen))) goto error;
|
al=*arraylen; *arraylen=0;
|
||||||
|
if (!(res=scan_asn1tag(src,max,&tc,&tt,&tag))) return 0;
|
||||||
|
if (tc!=UNIVERSAL || tt!=PRIMITIVE || tag!=OBJECT_IDENTIFIER) return 0;
|
||||||
|
if (!(tmp=scan_asn1length(src+res,max,&tlen))) return 0;
|
||||||
|
if (tlen<1) return 0; /* there has to be at least one octet */
|
||||||
res+=tmp;
|
res+=tmp;
|
||||||
|
if (max>src+res+tlen) max=src+res+tlen; /* clamp max down */
|
||||||
|
src+=res;
|
||||||
|
|
||||||
{
|
{
|
||||||
size_t i,x,y;
|
int a,b;
|
||||||
tmp=0;
|
a=(unsigned char)*src;
|
||||||
for(i=0;src[res+i]&128;++i)
|
b=a%40;
|
||||||
tmp=(tmp<<7)+((unsigned char)src[res+i]&(~128));
|
a/=40;
|
||||||
tmp=(tmp<<7)+(unsigned char)src[res+i]; ++i;
|
/* a can be 0, 1 or 2. And b is <=39 if a is 0 or 1.
|
||||||
x=tmp/40; y=tmp-x*40;
|
* So, if a is bigger than 2, it is really 2 */
|
||||||
/* AFAIK gilt fuer alle bisher zugewiesenen OIDs: x<=2 & y<40 */
|
if (a>2) {
|
||||||
#if 1
|
b+=(a-2)*40;
|
||||||
/* Hier wird das Beispiel aus dem Standard korrekt geparst. */
|
a=2;
|
||||||
while (x>2) { --x; y+=40; }
|
|
||||||
#else
|
|
||||||
/* Hier nicht. Dennoch arbeiten einige ASN.1 Parser ebenso. */
|
|
||||||
while (y>40) { y-=40; ++x; }
|
|
||||||
#endif
|
|
||||||
#if 0
|
|
||||||
buffer_putulong(buffer_2,x);
|
|
||||||
buffer_puts(buffer_2,".");
|
|
||||||
buffer_putulong(buffer_2,y);
|
|
||||||
#endif
|
|
||||||
for(;i<tlen;++i) {
|
|
||||||
tmp=0;
|
|
||||||
for(;src[res+i]&128;++i)
|
|
||||||
tmp=(tmp<<7)+((unsigned char)src[res+i]&(~128));
|
|
||||||
tmp=(tmp<<7)+(unsigned char)src[res+i];
|
|
||||||
#if 0
|
|
||||||
buffer_puts(buffer_2,".");
|
|
||||||
buffer_putulong(buffer_2,tmp);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
#if 0
|
if (array && cur<al) array[cur]=a; ++cur;
|
||||||
buffer_putsflush(buffer_2,"\n");
|
if (array && cur<al) array[cur]=b; ++cur;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
return res+tlen;
|
|
||||||
error:
|
for (++src; src<max; ) {
|
||||||
return 0;
|
size_t i;
|
||||||
|
unsigned long tmp;
|
||||||
|
if (!(i=scan_asn1tagint(src,max,&tmp)))
|
||||||
|
return 0;
|
||||||
|
src+=i;
|
||||||
|
if (array && cur<al) array[cur]=tmp; ++cur;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* if we got this far, then we have an OID, but it might not have fit */
|
||||||
|
*arraylen=cur;
|
||||||
|
if (cur>al) /* did not fit */
|
||||||
|
return 0;
|
||||||
|
return src-orig;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
size_t scan_asn1rawint(const char* src,const char* max,size_t len,long* l) {
|
size_t scan_asn1rawint(const char* src,const char* max,size_t len,long* l) {
|
||||||
size_t i,j;
|
size_t i,j;
|
||||||
long m;
|
long m;
|
||||||
|
if (src>=max) return 0;
|
||||||
if (*src<0) m=-1; else m=0;
|
if (*src<0) m=-1; else m=0;
|
||||||
for (i=j=0; i<len; ++i,++j) {
|
for (i=j=0; i<len; ++i,++j) {
|
||||||
if ((m==0 && *src==0) || (m==-1 && *src==-1)) --j;
|
if ((m==0 && *src==0) || (m==-1 && *src==-1)) --j;
|
||||||
|
|||||||
@@ -1,24 +1,15 @@
|
|||||||
#include "asn1.h"
|
#include "asn1.h"
|
||||||
|
|
||||||
size_t scan_asn1tag(const char* src,const char* max,enum asn1_tagclass* tc,enum asn1_tagtype* tt,unsigned long* tag) {
|
size_t scan_asn1tag(const char* src,const char* max,enum asn1_tagclass* tc,enum asn1_tagtype* tt,unsigned long* tag) {
|
||||||
const char* orig=src;
|
if (max<=src) return 0;
|
||||||
*tc=(*src&0xC0);
|
*tc=(*src&0xC0);
|
||||||
*tt=(*src&0x20);
|
*tt=(*src&0x20);
|
||||||
if (max<src) return 0;
|
|
||||||
/* The lower 5 bits are the tag, unless it's 0x1f, in which case the
|
/* The lower 5 bits are the tag, unless it's 0x1f, in which case the
|
||||||
* next bytes are the tag: always take the lower 7 bits; the last byte
|
* next bytes are the tag: always take the lower 7 bits; the last byte
|
||||||
* in the sequence is marked by a cleared high bit */
|
* in the sequence is marked by a cleared high bit */
|
||||||
if ((*src & 0x1f) == 0x1f) {
|
if ((*src & 0x1f) == 0x1f) {
|
||||||
unsigned long l=0;
|
size_t res=scan_asn1tagint(src+1,max,tag);
|
||||||
for (;;) {
|
return res+!!res; /* add 1 unless it's 0, then leave 0 */
|
||||||
++src;
|
|
||||||
if (src>max) return 0;
|
|
||||||
if (l>(((unsigned long)-1)>>7)) return 0; /* catch integer overflow */
|
|
||||||
l=l*128+(*src&0x7F);
|
|
||||||
if (!(*src&0x80)) break;
|
|
||||||
}
|
|
||||||
*tag=l;
|
|
||||||
return (src-orig+1);
|
|
||||||
} else {
|
} else {
|
||||||
*tag=*src&0x1f;
|
*tag=*src&0x1f;
|
||||||
return 1;
|
return 1;
|
||||||
|
|||||||
14
scan_asn1tagint.c
Normal file
14
scan_asn1tagint.c
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
#include "asn1.h"
|
||||||
|
|
||||||
|
size_t scan_asn1tagint(const char* src,const char* max,unsigned long* val) {
|
||||||
|
const char* orig=src;
|
||||||
|
unsigned long l=0;
|
||||||
|
for (;; ++src) {
|
||||||
|
if (src>=max) return 0;
|
||||||
|
if (l>(((unsigned long)-1)>>7)) return 0; /* catch integer overflow */
|
||||||
|
l=l*128+(*src&0x7F);
|
||||||
|
if (!(*src&0x80)) break;
|
||||||
|
}
|
||||||
|
*val=l;
|
||||||
|
return src-orig+1;
|
||||||
|
}
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include "asn1.h"
|
|
||||||
#include "ldap.h"
|
#include "ldap.h"
|
||||||
#include "buffer.h"
|
#include "buffer.h"
|
||||||
#include "byte.h"
|
#include "byte.h"
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
#include "asn1.h"
|
|
||||||
#include "ldap.h"
|
#include "ldap.h"
|
||||||
|
|
||||||
size_t scan_ldapava(const char* src,const char* max,struct AttributeValueAssertion* ava) {
|
size_t scan_ldapava(const char* src,const char* max,struct AttributeValueAssertion* ava) {
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
#include "asn1.h"
|
|
||||||
#include "ldap.h"
|
#include "ldap.h"
|
||||||
|
|
||||||
size_t scan_ldapbindrequest(const char* src,const char* max,
|
size_t scan_ldapbindrequest(const char* src,const char* max,
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
#include "asn1.h"
|
|
||||||
#include "ldap.h"
|
#include "ldap.h"
|
||||||
|
|
||||||
size_t scan_ldapbindresponse(const char* src,const char* max,
|
size_t scan_ldapbindresponse(const char* src,const char* max,
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
#include "asn1.h"
|
|
||||||
#include "ldap.h"
|
#include "ldap.h"
|
||||||
|
|
||||||
size_t scan_ldapdeleterequest(const char* src,const char* max,
|
size_t scan_ldapdeleterequest(const char* src,const char* max,
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
#include "asn1.h"
|
|
||||||
#include "ldap.h"
|
#include "ldap.h"
|
||||||
|
|
||||||
size_t scan_ldapmessage(const char* src,const char* max,
|
size_t scan_ldapmessage(const char* src,const char* max,
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include "asn1.h"
|
|
||||||
#include "ldap.h"
|
#include "ldap.h"
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
#include "asn1.h"
|
|
||||||
#include "ldap.h"
|
#include "ldap.h"
|
||||||
|
|
||||||
size_t scan_ldapresult(const char* src,const char* max,unsigned long* result,
|
size_t scan_ldapresult(const char* src,const char* max,unsigned long* result,
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
#include "asn1.h"
|
|
||||||
#include "ldap.h"
|
#include "ldap.h"
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
@@ -40,7 +39,7 @@ size_t scan_ldapsearchfilter(const char* src,const char* max,struct Filter** f)
|
|||||||
if (tc!=PRIVATE || (tt!=CONSTRUCTED && tag!=7) || tag>9) goto error;
|
if (tc!=PRIVATE || (tt!=CONSTRUCTED && tag!=7) || tag>9) goto error;
|
||||||
if (!(tmp=scan_asn1length(src+res,max,&len))) goto error;
|
if (!(tmp=scan_asn1length(src+res,max,&len))) goto error;
|
||||||
res+=tmp;
|
res+=tmp;
|
||||||
if (src+res+len>max) goto error;
|
if (src+res+len>=max) goto error;
|
||||||
if (!(*f=malloc(sizeof(struct Filter)))) goto error;
|
if (!(*f=malloc(sizeof(struct Filter)))) goto error;
|
||||||
(*f)->next=0;
|
(*f)->next=0;
|
||||||
(*f)->x=0;
|
(*f)->x=0;
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include "asn1.h"
|
|
||||||
#include "ldap.h"
|
#include "ldap.h"
|
||||||
|
|
||||||
size_t scan_ldapsearchrequest(const char* src,const char* max,
|
size_t scan_ldapsearchrequest(const char* src,const char* max,
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include "asn1.h"
|
|
||||||
#include "ldap.h"
|
#include "ldap.h"
|
||||||
|
|
||||||
size_t scan_ldapsearchresultentry(const char* src,const char* max,struct SearchResultEntry* sre) {
|
size_t scan_ldapsearchresultentry(const char* src,const char* max,struct SearchResultEntry* sre) {
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
#include <asn1.h>
|
#include "ldap.h"
|
||||||
#include <ldap.h>
|
|
||||||
|
|
||||||
size_t scan_ldapstring(const char* src,const char* max,struct string* s) {
|
size_t scan_ldapstring(const char* src,const char* max,struct string* s) {
|
||||||
return scan_asn1STRING(src,max,&s->s,&s->l);
|
return scan_asn1STRING(src,max,&s->s,&s->l);
|
||||||
|
|||||||
129
t10.c
Normal file
129
t10.c
Normal file
@@ -0,0 +1,129 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <byte.h>
|
||||||
|
#include "asn1.h"
|
||||||
|
|
||||||
|
void printasn1(const char* buf,const char* max) {
|
||||||
|
const char* maxstack[100];
|
||||||
|
size_t sptr=0;
|
||||||
|
size_t indent=0;
|
||||||
|
unsigned long tag;
|
||||||
|
enum asn1_tagclass tc;
|
||||||
|
enum asn1_tagtype tt;
|
||||||
|
size_t cl,len;
|
||||||
|
maxstack[sptr]=max;
|
||||||
|
while (buf<max) {
|
||||||
|
size_t i;
|
||||||
|
printf("%*s",indent,"");
|
||||||
|
cl=scan_asn1tag(buf,maxstack[sptr],&tc,&tt,&tag);
|
||||||
|
if (cl==0) {
|
||||||
|
printf("[could not parse tag]\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
printf("tag ");
|
||||||
|
switch (tc) {
|
||||||
|
case UNIVERSAL: printf("UNIVERSAL"); break;
|
||||||
|
case APPLICATION: printf("APPLICATION"); break;
|
||||||
|
case PRIVATE: printf("PRIVATE"); break;
|
||||||
|
case CONTEXT_SPECIFIC: printf("CONTEXT_SPECIFIC"); break;
|
||||||
|
default: printf("[illegal tag class 0x%x]\n",tc); return;
|
||||||
|
}
|
||||||
|
printf(" ");
|
||||||
|
switch (tt) {
|
||||||
|
case PRIMITIVE: printf("PRIMITIVE"); break;
|
||||||
|
case CONSTRUCTED: printf("CONSTRUCTED"); break;
|
||||||
|
default: printf("[illegal tag type 0x%x]\n",tt); return;
|
||||||
|
}
|
||||||
|
printf(" ");
|
||||||
|
if (tc!=UNIVERSAL)
|
||||||
|
printf("%d (0x%x)",tag,tag);
|
||||||
|
else switch (tag) {
|
||||||
|
case BOOLEAN: printf("BOOLEAN"); break;
|
||||||
|
case INTEGER: printf("INTEGER"); break;
|
||||||
|
case BIT_STRING: printf("BIT_STRING"); break;
|
||||||
|
case OCTET_STRING: printf("OCTET_STRING"); break;
|
||||||
|
case ENUMERATED: printf("ENUMERATED"); break;
|
||||||
|
case SEQUENCE_OF: printf("SEQUENCE_OF"); break;
|
||||||
|
case SET_OF: printf("SET_OF"); break;
|
||||||
|
case UTCTIME: printf("UTCTime"); break;
|
||||||
|
default: printf("[unsupported tag 0x%x]",tag); break;
|
||||||
|
}
|
||||||
|
|
||||||
|
buf+=cl;
|
||||||
|
cl=scan_asn1length(buf,maxstack[sptr],&len);
|
||||||
|
if (cl==0) {
|
||||||
|
puts("[could not parse length]");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
printf(" length %zu\n",len);
|
||||||
|
buf+=cl;
|
||||||
|
|
||||||
|
if (tc==UNIVERSAL && tt==PRIMITIVE) {
|
||||||
|
if (tag==INTEGER) {
|
||||||
|
unsigned long l;
|
||||||
|
size_t mlen;
|
||||||
|
mlen=scan_asn1rawint(buf,maxstack[sptr],cl,&l);
|
||||||
|
if (mlen)
|
||||||
|
printf("%*s-> %ld\n",indent,"",l);
|
||||||
|
} else if (tag==OCTET_STRING) {
|
||||||
|
printf("%*s-> \"",indent,"");
|
||||||
|
for (i=0; i<len; ++i) {
|
||||||
|
if (buf[i]<' ')
|
||||||
|
printf("\\x%02x",buf[i]);
|
||||||
|
else
|
||||||
|
putchar(buf[i]);
|
||||||
|
}
|
||||||
|
printf("\"\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tt==CONSTRUCTED) {
|
||||||
|
printf("%*s{\n",indent,"");
|
||||||
|
indent+=2;
|
||||||
|
if (sptr>=99) {
|
||||||
|
printf("too many nested constructed elements!\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
maxstack[++sptr]=buf+len;
|
||||||
|
} else
|
||||||
|
buf+=len;
|
||||||
|
|
||||||
|
while (sptr && maxstack[sptr]<=buf) {
|
||||||
|
--sptr;
|
||||||
|
indent-=2;
|
||||||
|
printf("%*s}\n",indent,"");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
main() {
|
||||||
|
char buf[1024];
|
||||||
|
int l,i;
|
||||||
|
byte_zero(buf,1024);
|
||||||
|
l=fmt_asn1generic(buf,"a{is}",8,23,"fnord");
|
||||||
|
printf("formatted into %d bytes\n",l);
|
||||||
|
{
|
||||||
|
printf("-> ");
|
||||||
|
for (i=0; i<l; ++i)
|
||||||
|
printf("%02x ",(unsigned char)(buf[i]));
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
printasn1(buf,buf+l);
|
||||||
|
|
||||||
|
|
||||||
|
{
|
||||||
|
unsigned long a;
|
||||||
|
unsigned long a2;
|
||||||
|
unsigned long b;
|
||||||
|
struct string c;
|
||||||
|
l=scan_asn1generic(buf,buf+l,"a{!is}",&a,&a2,&b,&c);
|
||||||
|
printf("%lu\n",l);
|
||||||
|
if (l) {
|
||||||
|
printf("got application tag %d (should be 8)\n",a);
|
||||||
|
printf("got sequence length %d\n",a2);
|
||||||
|
printf("got integer %d (should be 23)\n",b);
|
||||||
|
printf("got string \"%.*s\" (should be \"fnord\")\n",c.l,c.s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
1
t2.c
1
t2.c
@@ -2,7 +2,6 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include "mmap.h"
|
#include "mmap.h"
|
||||||
#include "asn1.h"
|
|
||||||
#include "ldap.h"
|
#include "ldap.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -639,7 +639,7 @@ static void tagmatches(uint32* index,size_t elements,struct string* s,
|
|||||||
setbit(b,rec);
|
setbit(b,rec);
|
||||||
/* there may be multiple matches.
|
/* there may be multiple matches.
|
||||||
* Look before and after mid, too */
|
* Look before and after mid, too */
|
||||||
if (mid) /* thx Andreas Stührk */
|
if (mid) /* thx Andreas Stührk */
|
||||||
for (k=mid-1; k>0; --k) {
|
for (k=mid-1; k>0; --k) {
|
||||||
m=uint32_read((char*)(&index[k]));
|
m=uint32_read((char*)(&index[k]));
|
||||||
if ((ft==LESSEQUAL) || (l=match(s,map+m))==0) {
|
if ((ft==LESSEQUAL) || (l=match(s,map+m))==0) {
|
||||||
|
|||||||
Reference in New Issue
Block a user