add oid and bitstring parsing and formatting to "generic" format string
routines, test them in t10.c
This commit is contained in:
4
Makefile
4
Makefile
@@ -12,7 +12,7 @@ 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 scan_asn1BITSTRING.o \
|
fmt_asn1sintpayload.o scan_asn1oid.o scan_asn1BITSTRING.o \
|
||||||
scan_asn1tagint.o fmt_asn1tagint.o fmt_asn1OID.o scan_asn1generic.o \
|
scan_asn1tagint.o fmt_asn1tagint.o fmt_asn1OID.o scan_asn1generic.o \
|
||||||
fmt_asn1generic.o
|
fmt_asn1generic.o scan_asn1rawoid.o fmt_asn1bitstring.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 \
|
||||||
@@ -128,6 +128,7 @@ 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_asn1OID.o: fmt_asn1OID.c asn1.h
|
||||||
fmt_asn1generic.o: fmt_asn1generic.c asn1.h
|
fmt_asn1generic.o: fmt_asn1generic.c asn1.h
|
||||||
|
fmt_asn1bitstring.o: fmt_asn1bitstring.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
|
||||||
@@ -139,6 +140,7 @@ 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_asn1rawoid.o: scan_asn1rawoid.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
|
||||||
|
|||||||
4
THANKS
4
THANKS
@@ -2,7 +2,7 @@ Trevor Harrison found a bug in fmt_asn1tag for the multibyte encoding.
|
|||||||
|
|
||||||
David Lichteblau found lots of problems in the ASN.1 code.
|
David Lichteblau found lots of problems in the ASN.1 code.
|
||||||
|
|
||||||
Özgür Kesim helped fix the substring search.
|
Özgür Kesim helped fix the substring search.
|
||||||
|
|
||||||
Thomas Walpuski has found lots of problems with the LDAP code.
|
Thomas Walpuski has found lots of problems with the LDAP code.
|
||||||
|
|
||||||
@@ -10,5 +10,5 @@ Dirk Meyer helped BSD portability.
|
|||||||
|
|
||||||
Zak Johnson fixed substring matches in ldap_match_mapped.
|
Zak Johnson fixed substring matches in ldap_match_mapped.
|
||||||
|
|
||||||
Andreas Stührk found a possible integer underflow in the indexing code.
|
Andreas Stührk found a possible integer underflow in the indexing code.
|
||||||
I'd be astounded if someone found a way to exploit it, though.
|
I'd be astounded if someone found a way to exploit it, though.
|
||||||
|
|||||||
16
asn1.h
16
asn1.h
@@ -76,6 +76,11 @@ size_t fmt_asn1transparent(char* dest,enum asn1_tagclass tc,
|
|||||||
size_t fmt_asn1string(char* dest,enum asn1_tagclass tc,enum asn1_tagtype tt,
|
size_t fmt_asn1string(char* dest,enum asn1_tagclass tc,enum asn1_tagtype tt,
|
||||||
enum asn1_tag tag,const char* c,size_t l);
|
enum asn1_tag tag,const char* c,size_t l);
|
||||||
|
|
||||||
|
/* same but for bitstrings.
|
||||||
|
* l in this case means the number of BITS in c, not bytes */
|
||||||
|
size_t fmt_asn1bitstring(char* dest,enum asn1_tagclass tc,enum asn1_tagtype tt,
|
||||||
|
enum asn1_tag tag,const char* c,size_t l);
|
||||||
|
|
||||||
/* write ASN.1 OCTET STRING */
|
/* write ASN.1 OCTET STRING */
|
||||||
#define fmt_asn1OCTETSTRING(dest,c,l) fmt_asn1string(dest,UNIVERSAL,PRIMITIVE,OCTET_STRING,c,l)
|
#define fmt_asn1OCTETSTRING(dest,c,l) fmt_asn1string(dest,UNIVERSAL,PRIMITIVE,OCTET_STRING,c,l)
|
||||||
|
|
||||||
@@ -94,7 +99,7 @@ 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);
|
size_t fmt_asn1OID(char* dest,enum asn1_tagclass tc,enum asn1_tagtype tt,enum asn1_tag tag,const unsigned long* array,unsigned long len);
|
||||||
|
|
||||||
|
|
||||||
/* conventions for the parser routines:
|
/* conventions for the parser routines:
|
||||||
@@ -141,11 +146,18 @@ size_t scan_asn1SET(const char* src,const char* max,size_t* len);
|
|||||||
* Return numbers of bytes parsed or 0 on error.
|
* 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
|
* 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 */
|
* 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);
|
size_t scan_asn1oid(const char* src,const char* max,unsigned long* array,size_t* arraylen);
|
||||||
|
/* internal helper, assumes you already read tag and length and max=src+length */
|
||||||
|
size_t scan_asn1rawoid(const char* src,const char* max,unsigned long* array,size_t* arraylen);
|
||||||
|
|
||||||
struct string {
|
struct string {
|
||||||
size_t l;
|
size_t l;
|
||||||
const char* s;
|
const char* s;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct oid {
|
||||||
|
size_t l;
|
||||||
|
size_t* a;
|
||||||
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
#include "asn1.h"
|
#include "asn1.h"
|
||||||
|
|
||||||
size_t fmt_asn1OID(char* dest,const unsigned long* array,unsigned long len) {
|
size_t fmt_asn1OID(char* dest,enum asn1_tagclass tc,enum asn1_tagtype tt,enum asn1_tag tag,const unsigned long* array,unsigned long len) {
|
||||||
size_t i,l,l2;
|
size_t i,l,l2;
|
||||||
if (len<2) return 0;
|
if (len<2) return 0;
|
||||||
for (l=1,i=2; i<len; ++i) {
|
for (l=1,i=2; i<len; ++i) {
|
||||||
l+=fmt_asn1tagint(dest,array[i]);
|
l+=fmt_asn1tagint(dest,array[i]);
|
||||||
}
|
}
|
||||||
l2=fmt_asn1transparent(dest,UNIVERSAL,PRIMITIVE,OBJECT_IDENTIFIER,l);
|
l2=fmt_asn1transparent(dest,tc,tt,tag,l);
|
||||||
if (!dest) return l+l2;
|
if (!dest) return l+l2;
|
||||||
dest[l2]=array[0]*40+array[1];
|
dest[l2]=array[0]*40+array[1];
|
||||||
dest+=l2+1;
|
dest+=l2+1;
|
||||||
|
|||||||
19
fmt_asn1bitstring.c
Normal file
19
fmt_asn1bitstring.c
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
#include "asn1.h"
|
||||||
|
#include "byte.h"
|
||||||
|
|
||||||
|
/* like fmt_asn1string, but l is in BITS, not BYTES */
|
||||||
|
size_t fmt_asn1bitstring(char* dest,enum asn1_tagclass tc,enum asn1_tagtype tt,enum asn1_tag tag,const char* c,size_t l) {
|
||||||
|
size_t len;
|
||||||
|
size_t actuallen;
|
||||||
|
if (l>(size_t)-100) return (size_t)-1;
|
||||||
|
actuallen=1+(l+7)/8; /* add one octet to specify the unused bits in the last octet, and calculate octets needed */
|
||||||
|
len=fmt_asn1transparent(dest,tc,tt,tag,actuallen);
|
||||||
|
if (dest) {
|
||||||
|
if (l)
|
||||||
|
dest[len]=7-((l-1)%8);
|
||||||
|
else
|
||||||
|
dest[len]=0;
|
||||||
|
byte_copy(dest+len+1,actuallen-1,c);
|
||||||
|
}
|
||||||
|
return len+actuallen;
|
||||||
|
}
|
||||||
@@ -9,6 +9,7 @@ size_t fmt_asn1generic(char* dest,const char* fmt,...) {
|
|||||||
va_start(args,fmt);
|
va_start(args,fmt);
|
||||||
unsigned long* application=0;
|
unsigned long* application=0;
|
||||||
struct string* s;
|
struct string* s;
|
||||||
|
struct oid* o;
|
||||||
struct string S;
|
struct string S;
|
||||||
size_t curlen=0;
|
size_t curlen=0;
|
||||||
size_t cursor=0;
|
size_t cursor=0;
|
||||||
@@ -31,6 +32,14 @@ size_t fmt_asn1generic(char* dest,const char* fmt,...) {
|
|||||||
application=NULL;
|
application=NULL;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case 'b': // send BIT_STRING, using struct string* as arg (expect l to be in bits, not bytes)
|
||||||
|
s=va_arg(args,struct string*);
|
||||||
|
if (application)
|
||||||
|
curlen=fmt_asn1bitstring(realdest,APPLICATION,PRIMITIVE,*application,s->s,s->l);
|
||||||
|
else
|
||||||
|
curlen=fmt_asn1bitstring(realdest,UNIVERSAL,PRIMITIVE,BIT_STRING,s->s,s->l);
|
||||||
|
application=NULL;
|
||||||
|
break;
|
||||||
case 'S': // send OCTET_STRING, using struct string* as arg
|
case 'S': // send OCTET_STRING, using struct string* as arg
|
||||||
s=va_arg(args,struct string*);
|
s=va_arg(args,struct string*);
|
||||||
copystring:
|
copystring:
|
||||||
@@ -45,6 +54,14 @@ copystring:
|
|||||||
S.l=strlen(S.s);
|
S.l=strlen(S.s);
|
||||||
s=&S;
|
s=&S;
|
||||||
goto copystring;
|
goto copystring;
|
||||||
|
case 'o': // send OBJECT_IDENTIFIER, using struct oid* as arg
|
||||||
|
o=va_arg(args,struct oid*);
|
||||||
|
if (application)
|
||||||
|
curlen=fmt_asn1OID(realdest,APPLICATION,PRIMITIVE,*application,o->a,o->l);
|
||||||
|
else
|
||||||
|
curlen=fmt_asn1OID(realdest,UNIVERSAL,PRIMITIVE,OBJECT_IDENTIFIER,o->a,o->l);
|
||||||
|
application=NULL;
|
||||||
|
break;
|
||||||
case '{': // start SEQUENCE
|
case '{': // start SEQUENCE
|
||||||
if (application)
|
if (application)
|
||||||
curlen=fmt_asn1tag(realdest,APPLICATION,CONSTRUCTED,*application);
|
curlen=fmt_asn1tag(realdest,APPLICATION,CONSTRUCTED,*application);
|
||||||
|
|||||||
2
ldap.h
2
ldap.h
@@ -1,9 +1,9 @@
|
|||||||
#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>
|
||||||
|
#include "asn1.h"
|
||||||
|
|
||||||
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);
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ size_t scan_asn1BITSTRING(const char* src,const char* max,const char** s,size_t*
|
|||||||
lastbyte=(*s)[*l+1];
|
lastbyte=(*s)[*l+1];
|
||||||
if (lastbyte & (0xff >> (8-**s)))
|
if (lastbyte & (0xff >> (8-**s)))
|
||||||
return 0;
|
return 0;
|
||||||
*l=*l*8-(unsigned char)(**s);
|
*l=(*l-1)*8-(unsigned char)(**s);
|
||||||
++*s;
|
++*s;
|
||||||
return tmp;
|
return tmp;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
#include <stdlib.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include "asn1.h"
|
#include "asn1.h"
|
||||||
|
|
||||||
@@ -36,6 +37,7 @@ size_t scan_asn1generic(const char* src,const char* max,const char* fmt,...) {
|
|||||||
application=0;
|
application=0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case 'b': // s = BIT STRING
|
||||||
case 's': // s = STRING
|
case 's': // s = STRING
|
||||||
{
|
{
|
||||||
struct string* dest=va_arg(args,struct string*);
|
struct string* dest=va_arg(args,struct string*);
|
||||||
@@ -47,13 +49,47 @@ size_t scan_asn1generic(const char* src,const char* max,const char* fmt,...) {
|
|||||||
if (tc!=APPLICATION) return 0;
|
if (tc!=APPLICATION) return 0;
|
||||||
*application=tag;
|
*application=tag;
|
||||||
} else {
|
} else {
|
||||||
if (tc!=UNIVERSAL || tt!=PRIMITIVE || tag!=OCTET_STRING)
|
if (tc!=UNIVERSAL || tt!=PRIMITIVE || tag!=(*fmt=='s'?OCTET_STRING:BIT_STRING))
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
if (*fmt=='b') { // additional checks for bit strings
|
||||||
|
if (dest->l==0 || // length can't be 0 because the format starts with 1 octet that contains the number of unused bits in the last octet
|
||||||
|
((unsigned char)(dest->s[0])>7) || // it's the number of unused bits in an octet, must be [0..7]
|
||||||
|
(dest->l==1 && dest->s[0])) return 0; // if there is no last octet, there can't be any unused bits in there
|
||||||
|
dest->l=(dest->l-1)*8-dest->s[0];
|
||||||
|
dest->s+=1;
|
||||||
|
}
|
||||||
src+=curlen;
|
src+=curlen;
|
||||||
application=0;
|
application=0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case 'o': // o == OID
|
||||||
|
{
|
||||||
|
struct oid* dest=va_arg(args,struct oid*);
|
||||||
|
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!=PRIMITIVE || tag!=OBJECT_IDENTIFIER)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
src+=curlen;
|
||||||
|
curlen=scan_asn1length(src,maxstack[curmax],&seqlen);
|
||||||
|
if (!curlen) return 0;
|
||||||
|
src+=curlen;
|
||||||
|
curlen=scan_asn1rawoid(src,src+seqlen,dest->a,&dest->l);
|
||||||
|
if (!curlen) {
|
||||||
|
if (dest->l && !dest->a) {
|
||||||
|
dest->a=malloc(dest->l*sizeof(dest->a[0]));
|
||||||
|
curlen=scan_asn1rawoid(src,src+seqlen,dest->a,&dest->l);
|
||||||
|
}
|
||||||
|
if (!curlen) return 0;
|
||||||
|
}
|
||||||
|
src+=curlen;
|
||||||
|
application=0;
|
||||||
|
}
|
||||||
case 'a': // next tag class is APPLICATION instead of UNIVERSAL; write tag to unsigned long*
|
case 'a': // next tag class is APPLICATION instead of UNIVERSAL; write tag to unsigned long*
|
||||||
{
|
{
|
||||||
application=va_arg(args,unsigned long*);
|
application=va_arg(args,unsigned long*);
|
||||||
|
|||||||
@@ -1,49 +1,21 @@
|
|||||||
#include "asn1.h"
|
#include "asn1.h"
|
||||||
|
|
||||||
size_t scan_asn1oid(const char* src,const char* max,unsigned long* array,unsigned long* arraylen) {
|
size_t scan_asn1oid(const char* src,const char* max,unsigned long* array,size_t* arraylen) {
|
||||||
const char* orig=src;
|
size_t res,tlen;
|
||||||
size_t res,tlen,cur=0,al;
|
|
||||||
unsigned long tag,tmp;
|
unsigned long tag,tmp;
|
||||||
enum asn1_tagclass tc;
|
enum asn1_tagclass tc;
|
||||||
enum asn1_tagtype tt;
|
enum asn1_tagtype tt;
|
||||||
if (!arraylen) return 0;
|
if (!arraylen) return 0;
|
||||||
al=*arraylen; *arraylen=0;
|
if (!(res=scan_asn1tag(src,max,&tc,&tt,&tag)) ||
|
||||||
if (!(res=scan_asn1tag(src,max,&tc,&tt,&tag))) return 0;
|
(tc!=UNIVERSAL || tt!=PRIMITIVE || tag!=OBJECT_IDENTIFIER) ||
|
||||||
if (tc!=UNIVERSAL || tt!=PRIMITIVE || tag!=OBJECT_IDENTIFIER) return 0;
|
!(tmp=scan_asn1length(src+res,max,&tlen)) || tlen<1) {
|
||||||
if (!(tmp=scan_asn1length(src+res,max,&tlen))) return 0;
|
*arraylen=0;
|
||||||
if (tlen<1) return 0; /* there has to be at least one octet */
|
return 0;
|
||||||
|
}
|
||||||
res+=tmp;
|
res+=tmp;
|
||||||
if (max>src+res+tlen) max=src+res+tlen; /* clamp max down */
|
if (max>src+res+tlen) max=src+res+tlen; /* clamp max down */
|
||||||
src+=res;
|
src+=res;
|
||||||
|
|
||||||
{
|
return scan_asn1rawoid(src,max,array,arraylen);
|
||||||
int a,b;
|
|
||||||
a=(unsigned char)*src;
|
|
||||||
b=a%40;
|
|
||||||
a/=40;
|
|
||||||
/* a can be 0, 1 or 2. And b is <=39 if a is 0 or 1.
|
|
||||||
* So, if a is bigger than 2, it is really 2 */
|
|
||||||
if (a>2) {
|
|
||||||
b+=(a-2)*40;
|
|
||||||
a=2;
|
|
||||||
}
|
|
||||||
if (array && cur<al) array[cur]=a; ++cur;
|
|
||||||
if (array && cur<al) array[cur]=b; ++cur;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (++src; src<max; ) {
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
40
scan_asn1rawoid.c
Normal file
40
scan_asn1rawoid.c
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
#include "asn1.h"
|
||||||
|
|
||||||
|
size_t scan_asn1rawoid(const char* src,const char* max,unsigned long* array,size_t* arraylen) {
|
||||||
|
const char* orig=src;
|
||||||
|
size_t cur=0,al;
|
||||||
|
if (!arraylen) return 0;
|
||||||
|
al=*arraylen; *arraylen=0;
|
||||||
|
if (max-src<1) return 0; /* there has to be at least one octet */
|
||||||
|
|
||||||
|
{
|
||||||
|
int a,b;
|
||||||
|
a=(unsigned char)*src;
|
||||||
|
b=a%40;
|
||||||
|
a/=40;
|
||||||
|
/* a can be 0, 1 or 2. And b is <=39 if a is 0 or 1.
|
||||||
|
* So, if a is bigger than 2, it is really 2 */
|
||||||
|
if (a>2) {
|
||||||
|
b+=(a-2)*40;
|
||||||
|
a=2;
|
||||||
|
}
|
||||||
|
if (array && cur<al) array[cur]=a; ++cur;
|
||||||
|
if (array && cur<al) array[cur]=b; ++cur;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (++src; src<max; ) {
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
39
t10.c
39
t10.c
@@ -41,6 +41,7 @@ void printasn1(const char* buf,const char* max) {
|
|||||||
case INTEGER: printf("INTEGER"); break;
|
case INTEGER: printf("INTEGER"); break;
|
||||||
case BIT_STRING: printf("BIT_STRING"); break;
|
case BIT_STRING: printf("BIT_STRING"); break;
|
||||||
case OCTET_STRING: printf("OCTET_STRING"); break;
|
case OCTET_STRING: printf("OCTET_STRING"); break;
|
||||||
|
case OBJECT_IDENTIFIER: printf("OBJECT_IDENTIFIER"); break;
|
||||||
case ENUMERATED: printf("ENUMERATED"); break;
|
case ENUMERATED: printf("ENUMERATED"); break;
|
||||||
case SEQUENCE_OF: printf("SEQUENCE_OF"); break;
|
case SEQUENCE_OF: printf("SEQUENCE_OF"); break;
|
||||||
case SET_OF: printf("SET_OF"); break;
|
case SET_OF: printf("SET_OF"); break;
|
||||||
@@ -68,11 +69,23 @@ void printasn1(const char* buf,const char* max) {
|
|||||||
printf("%*s-> \"",indent,"");
|
printf("%*s-> \"",indent,"");
|
||||||
for (i=0; i<len; ++i) {
|
for (i=0; i<len; ++i) {
|
||||||
if (buf[i]<' ')
|
if (buf[i]<' ')
|
||||||
printf("\\x%02x",buf[i]);
|
printf("\\x%02x",(unsigned char)(buf[i]));
|
||||||
else
|
else
|
||||||
putchar(buf[i]);
|
putchar(buf[i]);
|
||||||
}
|
}
|
||||||
printf("\"\n");
|
printf("\"\n");
|
||||||
|
} else if (tag==OBJECT_IDENTIFIER) {
|
||||||
|
struct oid o;
|
||||||
|
size_t mlen;
|
||||||
|
unsigned long fnord[100];
|
||||||
|
o.l=100;
|
||||||
|
o.a=fnord;
|
||||||
|
mlen=scan_asn1rawoid(buf,maxstack[sptr],o.a,&o.l);
|
||||||
|
if (mlen) {
|
||||||
|
printf("%*s-> ",indent,"");
|
||||||
|
for (i=0; i<o.l; ++i)
|
||||||
|
printf("%d%s",o.a[i],i+1==o.l?"\n":".");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -96,11 +109,20 @@ void printasn1(const char* buf,const char* max) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const unsigned long oid[]={1,2,840,113549,1};
|
||||||
|
const unsigned long oidlen = sizeof(oid) / sizeof(oid[0]);
|
||||||
|
|
||||||
main() {
|
main() {
|
||||||
char buf[1024];
|
char buf[1024];
|
||||||
int l,i;
|
int l,i;
|
||||||
|
struct oid o;
|
||||||
|
struct string B;
|
||||||
|
B.s="\xfe\x74";
|
||||||
|
B.l=8+6;
|
||||||
|
o.l=oidlen;
|
||||||
|
o.a=oid;
|
||||||
byte_zero(buf,1024);
|
byte_zero(buf,1024);
|
||||||
l=fmt_asn1generic(buf,"a{is}",8,23,"fnord");
|
l=fmt_asn1generic(buf,"a{isbo}",8,23,"fnord",&B,&o);
|
||||||
printf("formatted into %d bytes\n",l);
|
printf("formatted into %d bytes\n",l);
|
||||||
{
|
{
|
||||||
printf("-> ");
|
printf("-> ");
|
||||||
@@ -117,13 +139,24 @@ main() {
|
|||||||
unsigned long a2;
|
unsigned long a2;
|
||||||
unsigned long b;
|
unsigned long b;
|
||||||
struct string c;
|
struct string c;
|
||||||
l=scan_asn1generic(buf,buf+l,"a{!is}",&a,&a2,&b,&c);
|
struct oid d;
|
||||||
|
struct string e;
|
||||||
|
l=scan_asn1generic(buf,buf+l,"a{!isbo}",&a,&a2,&b,&c,&e,&d);
|
||||||
printf("%lu\n",l);
|
printf("%lu\n",l);
|
||||||
if (l) {
|
if (l) {
|
||||||
printf("got application tag %d (should be 8)\n",a);
|
printf("got application tag %d (should be 8)\n",a);
|
||||||
printf("got sequence length %d\n",a2);
|
printf("got sequence length %d\n",a2);
|
||||||
printf("got integer %d (should be 23)\n",b);
|
printf("got integer %d (should be 23)\n",b);
|
||||||
printf("got string \"%.*s\" (should be \"fnord\")\n",c.l,c.s);
|
printf("got string \"%.*s\" (should be \"fnord\")\n",c.l,c.s);
|
||||||
|
|
||||||
|
printf("got bitstring length %d: ",e.l);
|
||||||
|
for (i=0; i*8<e.l; ++i)
|
||||||
|
printf("%02x",(unsigned char)e.s[i]);
|
||||||
|
printf("\n");
|
||||||
|
|
||||||
|
printf("got oid ");
|
||||||
|
for (i=0; i<d.l; ++i)
|
||||||
|
printf("%d%s",d.a[i],i+1<d.l?".":" (should be 1.2.840.113549.1)\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user