From d184c99cf9b88c752ab6e070411a1b048548065b Mon Sep 17 00:00:00 2001 From: leitner Date: Tue, 27 Sep 2011 20:07:13 +0000 Subject: [PATCH] add asn1dump and support more OIDs expand fmt_asn1generic --- Makefile | 19 ++++++++++++++++--- asn1.h | 18 +++++++++++++++--- asn1dump.c | 23 +++++++++++++++++++++++ asn1oid.c | 44 ++++++++++++++++++++++++++++++++++++++------ fmt_asn1generic.c | 40 +++++++++++++++++++++++++++++++++++++++- printasn1.c | 36 +++++++++++++++++++----------------- scan_asn1generic.c | 1 + scan_asn1oid.c | 2 +- scan_asn1rawoid.c | 2 +- 9 files changed, 153 insertions(+), 32 deletions(-) create mode 100644 asn1dump.c diff --git a/Makefile b/Makefile index 374ccc7..70d826b 100644 --- a/Makefile +++ b/Makefile @@ -3,7 +3,7 @@ all: t1 t2 parse dumpidx idx2ldif addindex bindrequest tinyldap \ tinyldap_standalone tinyldap_debug ldapclient ldapclient_str \ -md5password mysql2ldif acl dumpacls ldapdelete # t6 # t +md5password mysql2ldif acl dumpacls ldapdelete asn1dump # t6 # t asn1.a: fmt_asn1intpayload.o fmt_asn1length.o fmt_asn1tag.o \ fmt_asn1int.o fmt_asn1string.o fmt_asn1transparent.o scan_asn1tag.o \ @@ -38,7 +38,9 @@ mduptab_init.o mduptab_init_reuse.o mduptab_reset.o auth.a: auth.o DIET=/opt/diet/bin/diet -Os -CC=gcc +CROSS= +#CROSS=i686-mingw32- +CC=$(CROSS)gcc CFLAGS=-pipe -I. -Wall -W -Wextra ifneq ($(DEBUG),) DIET=/opt/diet/bin/diet @@ -55,11 +57,15 @@ else LIBS+=-lcrypto -lcrypt endif +ifeq ($(CROSS),i686-mingw32-) +EXE=.exe +endif + %.o: %.c $(DIET) $(CC) $(CFLAGS) -c $< %.a: - ar cru $@ $^ + $(CROSS)ar cru $@ $^ %: %.c $(DIET) $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) -lowfat ${LIBS} @@ -73,6 +79,10 @@ bindrequest tinyldap tinyldap_standalone tinyldap_debug ldapclient ldapclient_st idx2ldif: ldap.a dumpacls: ldap.a asn1.a parse: normalize_dn.o +asn1dump: asn1dump.c printasn1.c asn1.a + $(DIET) $(CC) $(CFLAGS) -o $@$(EXE) $< $(LDFLAGS) -lowfat asn1.a + +asn1dump.o: printasn1.c tinyldap_standalone: tinyldap.c $(DIET) $(CC) $(CFLAGS) -DSTANDALONE -o $@ $^ $(LDFLAGS) -lowfat $(LIBS) @@ -162,3 +172,6 @@ scan_asn1generic.o: scan_asn1generic.c asn1.h asn1oid.o: asn1oid.c asn1.h ldap_match_sre.o: ldap_match_sre.c ldap.h + +windoze: + $(MAKE) DIET= CROSS=i686-mingw32- asn1dump diff --git a/asn1.h b/asn1.h index 4ddd68e..78351b7 100644 --- a/asn1.h +++ b/asn1.h @@ -149,9 +149,9 @@ size_t scan_asn1SET(const char* src,const char* max,size_t* len); * 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,size_t* arraylen); +size_t scan_asn1oid(const char* src,const char* max,size_t* 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); +size_t scan_asn1rawoid(const char* src,const char* max,size_t* array,size_t* arraylen); struct string { size_t l; @@ -171,6 +171,9 @@ enum x509_oid { X509_ATTR_GENERATIONQUALIFIER, X509_ATTR_UNIQID, X509_ATTR_DNQUALIFIER, X509_ATTR_EMAIL, + X509_SIGNEDDATA, X509_DATA, X509_CONTENTTYPE, X509_MESSAGEDIGEST, X509_SIGNINGTIME, + X509_PKCS2, X509_NETSCAPE_CERTTYPE, X509_SMIME_CAPABILITIES, + X509_EXT_SUBJKEYID, X509_EXT_KEYUSAGE, X509_EXT_PRIVKEYUSAGEPERIOD, X509_EXT_SUBJALTNAME, X509_EXT_ISSUERALTNAME, X509_EXT_BASICCONSTRAINTS, X509_EXT_CRL_NUMBER, X509_EXT_REASONCODE, X509_EXT_INSTRUCTIONCODE, @@ -181,7 +184,16 @@ enum x509_oid { X509_ALG_MD2RSA, X509_ALG_MD4RSA, X509_ALG_MD5RSA, X509_ALG_SHA1RSA, X509_ALG_SHA256RSA, X509_ALG_SHA384RSA, X509_ALG_SHA512RSA, - X509_ALG_SHA224RSA, X509_ALG_RSA, + X509_ALG_SHA224RSA, X509_ALG_RSA, X509_ALG_MD4, X509_ALG_MD5, + + X509_ALG_DES_ECB, X509_ALG_DES_CBC, X509_ALG_DES_OFB64, + X509_ALG_DES_CFB64, X509_ALG_RSASIGNATURE, X509_ALG_DSA_2, + X509_ALG_DSASHA, X509_ALG_SHARSA, X509_ALG_DES_EDE_ECB, X509_ALG_SHA, + X509_ALG_SHA1, X509_ALG_DSASHA1_2, X509_ALG_AES256_CBC, + X509_ALG_AES192_CBC, X509_ALG_AES128_CBC, X509_ALG_DES_EDE3_CBC, + X509_ALG_RC2_CBC, X509_ALG_RIPEMD, + + X509_ALG_GOSTR3411_94, X509_ALG_GOST28147_89, }; extern const struct oidlookup { diff --git a/asn1dump.c b/asn1dump.c new file mode 100644 index 0000000..7503f8e --- /dev/null +++ b/asn1dump.c @@ -0,0 +1,23 @@ +#include +#include +#include +#include "asn1.h" +#include "mmap.h" + +#include "printasn1.c" + +int main(int argc,char* argv[]) { + char* buf; + size_t l; + + if (argc<2) { + printf("usage: asn1dump filename\n"); + return 0; + } + buf=mmap_read(argv[1],&l); + if (buf) { + printasn1(buf,buf+l); + return 0; + } + return 1; +} diff --git a/asn1oid.c b/asn1oid.c index dfbdede..fa1242e 100644 --- a/asn1oid.c +++ b/asn1oid.c @@ -24,6 +24,14 @@ const struct oidlookup oid2string[] = { ENTRY("\x55\x04\x2e", "dnQualifier", X509_ATTR_DNQUALIFIER), ENTRY("\x2a\x86\x48\x86\xf7\x0d\x01\x09\x01", "emailAddress", X509_ATTR_EMAIL), + ENTRY("\x2a\x86\x48\x86\xf7\x0d\x01\x07\x02", "signedData", X509_SIGNEDDATA), + ENTRY("\x2a\x86\x48\x86\xf7\x0d\x01\x07\x01", "data", X509_DATA), + ENTRY("\x2a\x86\x48\x86\xf7\x0d\x01\x09\x03", "contentType", X509_CONTENTTYPE), + ENTRY("\x2a\x86\x48\x86\xf7\x0d\x01\x09\x04", "messageDigest", X509_MESSAGEDIGEST), + ENTRY("\x2a\x86\x48\x86\xf7\x0d\x01\x09\x05", "signingTime", X509_SIGNINGTIME), + ENTRY("\x60\x86\x48\x01\x86\xf8\x42\x01\x01", "netscapeCertType", X509_NETSCAPE_CERTTYPE), + ENTRY("\x2a\x86\x48\x86\xf7\x0d\x01\x09\x0f", "smimeCapabilities", X509_SMIME_CAPABILITIES), + /* X.509v3 extension OIDs */ ENTRY("\x55\x1d\x0e", "subject_key_identifier", X509_EXT_SUBJKEYID), ENTRY("\x55\x1d\x0f", "key_usage", X509_EXT_KEYUSAGE), @@ -44,15 +52,39 @@ const struct oidlookup oid2string[] = { ENTRY("\x55\x1d\x25", "ext_key_usage", X509_EXT_KEY_USAGE), /* X.509 algorithms */ + ENTRY("\x2a\x86\x48\x86\xf7\x0d\x01\x01\x01", "rsaEncryption", X509_ALG_RSA), ENTRY("\x2a\x86\x48\x86\xf7\x0d\x01\x01\x02", "md2WithRSAEncryption", X509_ALG_MD2RSA), ENTRY("\x2a\x86\x48\x86\xf7\x0d\x01\x01\x03", "md4WithRSAEncryption", X509_ALG_MD4RSA), ENTRY("\x2a\x86\x48\x86\xf7\x0d\x01\x01\x04", "md5WithRSAEncryption", X509_ALG_MD5RSA), - ENTRY("\x2a\x86\x48\x86\xf7\x0d\x01\x01\x05", "SHA1WithRSAEncryption", X509_ALG_SHA1RSA), - ENTRY("\x2a\x86\x48\x86\xf7\x0d\x01\x01\x0b", "SHA256WithRSAEncryption", X509_ALG_SHA256RSA), - ENTRY("\x2a\x86\x48\x86\xf7\x0d\x01\x01\x0c", "SHA384WithRSAEncryption", X509_ALG_SHA384RSA), - ENTRY("\x2a\x86\x48\x86\xf7\x0d\x01\x01\x0d", "SHA512WithRSAEncryption", X509_ALG_SHA512RSA), - ENTRY("\x2a\x86\x48\x86\xf7\x0d\x01\x01\x0e", "SHA224WithRSAEncryption", X509_ALG_SHA224RSA), - ENTRY("\x2a\x86\x48\x86\xf7\x0d\x01\x01\x01", "rsaEncryption", X509_ALG_RSA), + ENTRY("\x2a\x86\x48\x86\xf7\x0d\x01\x01\x05", "sha1WithRSAEncryption", X509_ALG_SHA1RSA), + ENTRY("\x2a\x86\x48\x86\xf7\x0d\x01\x01\x0b", "sha256WithRSAEncryption", X509_ALG_SHA256RSA), + ENTRY("\x2a\x86\x48\x86\xf7\x0d\x01\x01\x0c", "sha384WithRSAEncryption", X509_ALG_SHA384RSA), + ENTRY("\x2a\x86\x48\x86\xf7\x0d\x01\x01\x0d", "sha512WithRSAEncryption", X509_ALG_SHA512RSA), + ENTRY("\x2a\x86\x48\x86\xf7\x0d\x01\x01\x0e", "sha224WithRSAEncryption", X509_ALG_SHA224RSA), + ENTRY("\x2b\x0e\x03\x02\x03", "md5WithRSA", X509_ALG_MD5RSA), + ENTRY("\x2b\x0e\x03\x02\x06", "des_ecb", X509_ALG_DES_ECB), + ENTRY("\x2b\x0e\x03\x02\x07", "des_cbc", X509_ALG_DES_CBC), + ENTRY("\x2b\x0e\x03\x02\x08", "des_ofb64", X509_ALG_DES_OFB64), + ENTRY("\x2b\x0e\x03\x02\x08", "des_cfb64", X509_ALG_DES_CFB64), + ENTRY("\x2b\x0e\x03\x02\x0b", "rsaSignature", X509_ALG_RSASIGNATURE), + ENTRY("\x2b\x0e\x03\x02\x0c", "dsa_2", X509_ALG_DSA_2), + ENTRY("\x2b\x0e\x03\x02\x0d", "dsaWithSha", X509_ALG_DSASHA), + ENTRY("\x2b\x0e\x03\x02\x0f", "shaWithRSA", X509_ALG_SHARSA), + ENTRY("\x2b\x0e\x03\x02\x11", "des_ede_ecb", X509_ALG_DES_EDE_ECB), + ENTRY("\x2b\x0e\x03\x02\x12", "sha", X509_ALG_SHA), + ENTRY("\x2b\x0e\x03\x02\x1a", "sha1", X509_ALG_SHA1), + ENTRY("\x2b\x0e\x03\x02\x1b", "dsaWithSHA1_2", X509_ALG_DSASHA1_2), + ENTRY("\x2b\x0e\x03\x02\x1d", "sha1WithRSA", X509_ALG_SHA1RSA), + ENTRY("\x2a\x86\x48\x86\xf7\x0d\x02\x04", "md4", X509_ALG_MD4), + ENTRY("\x2a\x86\x48\x86\xf7\x0d\x02\x05", "md5", X509_ALG_MD5), + ENTRY("\x2b\x24\x03\x02\x01", "ripemd", X509_ALG_RIPEMD), + ENTRY("\x60\x86\x48\x01\x65\x03\x04\x01\x2a", "aes256_cbc", X509_ALG_AES256_CBC), + ENTRY("\x2a\x85\x03\x02\x02\x09", "GOST R 34.11-94", X509_ALG_GOSTR3411_94), + ENTRY("\x2a\x85\x03\x02\x02\x15", "GOST 28147-89", X509_ALG_GOST28147_89), + ENTRY("\x60\x86\x48\x01\x65\x03\x04\x01\x16", "aes192_cbc", X509_ALG_AES192_CBC), + ENTRY("\x60\x86\x48\x01\x65\x03\x04\x01\x02", "aes128_cbc", X509_ALG_AES128_CBC), + ENTRY("\x2a\x86\x48\x86\xf7\x0d\x03\x07", "des_ede3_cbc", X509_ALG_DES_EDE3_CBC), + ENTRY("\x2a\x86\x48\x86\xf7\x0d\x03\x02", "rc2_cbc", X509_ALG_RC2_CBC), }; diff --git a/fmt_asn1generic.c b/fmt_asn1generic.c index e63f967..c97ee96 100644 --- a/fmt_asn1generic.c +++ b/fmt_asn1generic.c @@ -16,6 +16,7 @@ size_t fmt_asn1generic(char* dest,const char* fmt,...) { size_t seqlen; unsigned long desttag=0; unsigned long appstore; + int stringtype; while (*fmt) { char* realdest=dest?dest+cursor:NULL; switch (*fmt) { @@ -23,6 +24,14 @@ size_t fmt_asn1generic(char* dest,const char* fmt,...) { appstore=va_arg(args,unsigned long); application=&appstore; break; + case '0': // UNIVERSAL PRIMITIVE NULL length 0 + if (application) + curlen=fmt_asn1tag(realdest,APPLICATION,PRIMITIVE,_NULL); + else + curlen=fmt_asn1tag(realdest,UNIVERSAL,PRIMITIVE,_NULL); + application=NULL; + curlen+=fmt_asn1length(realdest?realdest+curlen:NULL,0); + break; case 'i': // send integer { unsigned long i=va_arg(args,unsigned long); @@ -41,16 +50,38 @@ size_t fmt_asn1generic(char* dest,const char* fmt,...) { curlen=fmt_asn1bitstring(realdest,UNIVERSAL,PRIMITIVE,BIT_STRING,s->s,s->l); application=NULL; break; + case 'B': + stringtype=BIT_STRING; + goto stringcopy; + case 'A': + stringtype=IA5String; + goto stringcopy; + case 'P': + stringtype=PrintableString; + goto stringcopy; case 'S': // send OCTET_STRING, using struct string* as arg + stringtype=OCTET_STRING; +stringcopy: 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); + curlen=fmt_asn1string(realdest,UNIVERSAL,PRIMITIVE,stringtype,s->s,s->l); application=NULL; break; + case 't': + stringtype=UTCTIME; + goto stringcopy_alt; + case 'a': + stringtype=IA5String; + goto stringcopy_alt; + case 'p': + stringtype=PrintableString; + goto stringcopy_alt; case 's': // send OCTET_STRING, using const char* with strlen() as arg + stringtype=OCTET_STRING; +stringcopy_alt: S.s=va_arg(args,const char*); S.l=strlen(S.s); s=&S; @@ -63,6 +94,13 @@ copystring: curlen=fmt_asn1OID(realdest,UNIVERSAL,PRIMITIVE,OBJECT_IDENTIFIER,o->a,o->l); application=NULL; break; + + case 'C': // copy raw ASN.1 DER data, take struct string* + s=va_arg(args,struct string*); + if (realdest) memcpy(realdest,s->s,s->l); + curlen=s->l; + break; + case 'c': // start context specific section desttag=va_arg(args,unsigned long); // fall through diff --git a/printasn1.c b/printasn1.c index facd2eb..1b62f7b 100644 --- a/printasn1.c +++ b/printasn1.c @@ -11,7 +11,7 @@ void printasn1(const char* buf,const char* max) { maxstack[sptr]=max; while (buf %ld\n",indent,"",l); - } else if (tag==OCTET_STRING || tag==PrintableString || tag==IA5String || tag==UTCTIME) { - printf("%*s-> \"",indent,""); + printf("%*s-> %ld\n",(int)indent,"",l); + } else if (tag==OCTET_STRING || tag==PrintableString || tag==IA5String || tag==UTCTIME || tag==BIT_STRING) { + printf("%*s-> \"",(int)indent,""); for (i=0; i ",indent,""); + printf("%*s-> ",(int)indent,""); for (i=0; i=99) { printf("too many nested constructed elements!\n"); @@ -114,7 +116,7 @@ void printasn1(const char* buf,const char* max) { while (sptr && maxstack[sptr]<=buf) { --sptr; indent-=2; - printf("%*s}\n",indent,""); + printf("%*s}\n",(int)indent,""); } } diff --git a/scan_asn1generic.c b/scan_asn1generic.c index b00d0f2..c246efd 100644 --- a/scan_asn1generic.c +++ b/scan_asn1generic.c @@ -3,6 +3,7 @@ #include #include #include "asn1.h" +#include size_t scan_asn1generic(const char* src,const char* max,const char* fmt,...) { size_t curlen,seqlen; diff --git a/scan_asn1oid.c b/scan_asn1oid.c index acb9387..b5abf52 100644 --- a/scan_asn1oid.c +++ b/scan_asn1oid.c @@ -1,6 +1,6 @@ #include "asn1.h" -size_t scan_asn1oid(const char* src,const char* max,unsigned long* array,size_t* arraylen) { +size_t scan_asn1oid(const char* src,const char* max,size_t* array,size_t* arraylen) { size_t res,tlen; unsigned long tag,tmp; enum asn1_tagclass tc; diff --git a/scan_asn1rawoid.c b/scan_asn1rawoid.c index 36b0eb7..814009d 100644 --- a/scan_asn1rawoid.c +++ b/scan_asn1rawoid.c @@ -1,6 +1,6 @@ #include "asn1.h" -size_t scan_asn1rawoid(const char* src,const char* max,unsigned long* array,size_t* arraylen) { +size_t scan_asn1rawoid(const char* src,const char* max,size_t* array,size_t* arraylen) { const char* orig=src; size_t cur=0,al; if (!arraylen) return 0;