diff options
-rw-r--r-- | mduptab.h | 19 | ||||
-rw-r--r-- | mstorage.h | 33 | ||||
-rw-r--r-- | scan_certificate.c | 393 | ||||
-rw-r--r-- | strduptab.c | 30 | ||||
-rw-r--r-- | strduptab.h | 13 | ||||
-rw-r--r-- | strstorage.c | 29 | ||||
-rw-r--r-- | strstorage.h | 6 |
7 files changed, 0 insertions, 523 deletions
diff --git a/mduptab.h b/mduptab.h deleted file mode 100644 index 5704e87..0000000 --- a/mduptab.h +++ /dev/null @@ -1,19 +0,0 @@ -/* save memory for constant strings by keeping a list of the ones that - * we already saw and not allocating memory for each new one. The only - * API is "add string and return offset". The offset is relative to the - * root of the pstorage_t. Will try to insert the string in the table. - * If the same string was already there, it will return offset of that - * string, otherwise it will insert a copy of the new string. */ - -#include "mstorage.h" - -typedef struct mduptable { - mstorage_t table,strings; - mstorage_t* Strings; -} mduptab_t; - -void mduptab_init(mduptab_t* t); -void mduptab_init_reuse(mduptab_t* t,mstorage_t* s); -long mduptab_add(mduptab_t* t,const char* s,size_t len); -long mduptab_adds(mduptab_t* t,const char* s); -void mduptab_reset(mduptab_t* t); diff --git a/mstorage.h b/mstorage.h deleted file mode 100644 index 258e786..0000000 --- a/mstorage.h +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef _MSTORAGE_H -#define _MSTORAGE_H - -#include <stddef.h> - -/* (optionally persistent) mmapped storage. */ - -typedef struct mstorage { - char* root; - size_t mapped,used; - int fd; -} mstorage_t; - -void mstorage_init(mstorage_t* p); - -int mstorage_init_persistent(mstorage_t* p,int fd); - -/* Works like strstorage_add, but will return an - * offset to mstorage_root, which is mmapped and may thus change. */ -/* offset -1 ==> error */ -long mstorage_add(mstorage_t* p,const char* s,size_t n); - -/* undo mapping */ -void mstorage_unmap(mstorage_t* p); - -/* this is tinyldap specific. If the data contains at least one 0-byte, - * it is stored in a tinyldap specific encoding: - * char 0; - * uint32 len; - * char data[len] */ -long mstorage_add_bin(mstorage_t* p,const char* s,size_t n); - -#endif diff --git a/scan_certificate.c b/scan_certificate.c deleted file mode 100644 index 4cffcf7..0000000 --- a/scan_certificate.c +++ /dev/null @@ -1,393 +0,0 @@ -#include <stdlib.h> -#include <stdio.h> -#include "asn1.h" -#include <str.h> -#include "textcode.h" -#include "fmt.h" -#include "byte.h" - -struct x509signature { - struct string oid; /* you are not expected to actually decode this */ - size_t oididx; /* if this is (size_t)-1, then the parser did not know the OID. - Otherwise it's the index into oid2string. oid2string[oididx].id - should be something like X509_ALG_SHA1RSA (see asn1.h) */ - struct string bitstring; /* In this string, the length is in bits, not bytes! */ - /* If the length is not a multiple of 8, then the unused bits are missing in the last byte. - * The parser already validated that the last byte is padded with 0 bits */ -}; - -struct x509cert { - enum { v1=0, v1988=0, v2=1, v3=2, v1996=2 } version; - size_t serial; - struct x509signature algid; - struct string issuer; /* this is the raw asn.1 structure, a SET of "[{op}]" in scan_asn1generic terms */ - time_t notbefore, notafter; - struct string subject; /* this is the raw asn.1 structure, a SET of "[{op}]" in scan_asn1generic terms */ - struct x509signature sig; -}; - -struct rsaprivatekey { - size_t* modulus,* publicExponent,* privateExponent,* prime1,* prime2,* exponent1,* exponent2,* coefficient; - struct string otherPrimeInfos; - size_t* freewhendone; -}; - -struct dsaprivatekey { -}; - -void printasn1(const char* buf,const char* max); - -static int findindn(struct string* dn,enum x509_oid id,struct string* dest) { - size_t i; - const char* c=dn->s; - const char* max=dn->s+dn->l; - for (;;) { - struct string oid; - size_t l=scan_asn1generic(c,max,"[{op}]",&oid,dest); - if (l) { - i=lookupoid(oid.s,oid.l); - if (i!=(size_t)-1) { // recognized the oid! - if (oid2string[i].id==id) - return 1; - } - c+=l; - } else break; - } - return 0; -} - -static size_t base64_decode(const char* cert, size_t l, const char* name, char** dest) { - /* cert should be something like "-----BEGIN CERTIFICATE-----\n[base64 gunk]\n-----END CERTIFICATE-----\n" - * l should be strlen(cert), but cert does not need to be 0-terminated - * name should be something like "CERTIFICATE" or "RSA PRIVATE KEY", what you are trying to decode - * dest will end up pointing to the decoded data. - * return value can be 0 if we can't decode the data and it does not - * look like it's a binary certificate. Or it can be some length - * value, in which case dest points to a malloced area of that length - * with the decoded data in it. */ - size_t taglen=strlen(name)+sizeof("-----BEGIN -----")-1; - char tag[taglen+1]; - char* c=0,* x; - tag[fmt_strm(tag,"-----BEGIN ",name,"-----")]=0; - if (l > 2*taglen && byte_equal(cert,taglen,tag)) -certfound: - { - size_t cur,used; - /* "-----BEGIN CERTIFICATE-----", "-----END CERTIFICATE-----" and newlines */ - c=malloc((l-2*taglen)/4*3); - if (!c) return 0; - x=c; - for (cur=taglen; cur+taglen-1<l;) { - size_t next; - if (cert[cur]=='\r') ++cur; /* skip line ending */ - if (cert[cur]=='\n') ++cur; - next=scan_base64(cert+cur,x,&used); - if (next==0) break; - cur+=next; - x+=used; - } - if (!str_start(cert+cur,"-----END ") || - byte_diff(cert+cur+sizeof("-----END"),taglen-sizeof("----BEGIN")-1,tag+sizeof("-----BEGIN"))) { - free(c); - return 0; - } - cert=c; - l=x-c; - } else { - /* Maybe it has text in front of the BEGIN CERTIFICATE line */ - size_t i,a=1; - for (i=0; i+27+25+2<l; ++i) { - if (cert[i]!='\n' && cert[i]!='\r' && (cert[i]<' ' || cert[i]>'~')) { - a=0; - break; - } - if (byte_equal(cert+i,taglen,tag)) { - cert+=i; - l-=i; - goto certfound; - } - } - if (a) /* if we end up here, it was ascii but did not contain a certificate. fail. */ - return 0; - } - /* if we end up here, we decoded some base64 data or we found some - * binary data. See if it looks like x.509 at all. If it does, it - * starts with a SEQUENCE_OF, which encodes as '0'. */ - if (*cert!='0') { -parseerror: - free(c); - return 0; - } - *dest=c; - return l; -} - -size_t scan_rsaprivatekey(const char* cert, size_t l, struct rsaprivatekey* C, char** freewhendone) { - char* c; - size_t maxdigits,ret; - unsigned long version; - *freewhendone=NULL; - l=base64_decode(cert,l,"RSA PRIVATE KEY",&c); - if (!l) return 0; - if (c!=cert) *freewhendone=c; - maxdigits=l/sizeof(size_t)+2; - C->freewhendone=malloc(maxdigits*sizeof(size_t)*8); - if (!C->freewhendone) { -fail: - free(*freewhendone); - freewhendone=NULL; - return 0; - } - C->modulus=C->freewhendone; - C->publicExponent=C->modulus+maxdigits; - C->privateExponent=C->publicExponent+maxdigits; - C->prime1=C->privateExponent+maxdigits; - C->prime2=C->prime1+maxdigits; - C->exponent1=C->prime2+maxdigits; - C->exponent2=C->exponent1+maxdigits; - C->coefficient=C->exponent2+maxdigits; - C->otherPrimeInfos.l=0; - C->otherPrimeInfos.s=NULL; - if ((ret=scan_asn1generic(c,c+l,"{iIIIIIIII!}",&version, - C->modulus,C->publicExponent,C->privateExponent, - C->prime1,C->prime2,C->exponent1,C->exponent2, - C->coefficient,&C->otherPrimeInfos))) { - if (version!=0 && version!=1) goto fail; - if (version==0 && C->otherPrimeInfos.l) goto fail; - if (version==1 && !C->otherPrimeInfos.l) goto fail; - if (version==0) C->otherPrimeInfos.s=NULL; - return ret; - } else - goto fail; -} - -size_t scan_certificate(const char* cert, size_t l, struct x509cert* C, char** freewhendone) { - char* c=0,* x; - *freewhendone=NULL; - l=base64_decode(cert,l,"CERTIFICATE",&c); - if (!l) return 0; - if (c!=cert) *freewhendone=c; - cert=c; - - /* now for the heavy lifting */ - { - unsigned long tagforversion; // must be 0 - unsigned long version; - struct string oidalg,algparams,pubkeyalg,extensions,oidsig,sigrest,sigdata; - size_t n,i; - if ((n=scan_asn1generic(cert,cert+l,"{{ci]i{o!}{!}{uu}{!}{!}!}{o!}b}", - &tagforversion, - &version, - &C->serial, - &oidalg, &algparams, - &C->issuer, - &C->notbefore, &C->notafter, - &C->subject, - &pubkeyalg, - &extensions, - &oidsig, &sigrest, &sigdata))) { - - if (version==0) - printf("X.509 certificate\n"); - else if (version==1) - printf("X.509v2 certificate\n"); - else if (version==2) - printf("X.509v3 certificate\n"); - else - printf("unsupported version %ld (must be 0, 1 or 2)\n",version); - - printf("serial number %lu\n",C->serial); - - printf("issuer: "); - { - struct string s; - if (findindn(&C->issuer,X509_ATTR_COUNTRY,&s)) - printf("C=%.*s ",(int)s.l,s.s); - if (findindn(&C->issuer,X509_ATTR_ORG,&s)) - printf("O=%.*s ",(int)s.l,s.s); - if (findindn(&C->issuer,X509_ATTR_COMMONNAME,&s)) - printf("CN=%.*s ",(int)s.l,s.s); - } - printf("\n"); - - { - char a[100],b[100]; - a[fmt_httpdate(a,C->notbefore)]=0; - b[fmt_httpdate(b,C->notafter)]=0; - printf("valid not before %s and not after %s\n",a,b); - } - - printf("subject: "); - { - struct string s; - if (findindn(&C->issuer,X509_ATTR_COUNTRY,&s)) - printf("C=%.*s ",(int)s.l,s.s); - if (findindn(&C->issuer,X509_ATTR_ORG,&s)) - printf("O=%.*s ",(int)s.l,s.s); - if (findindn(&C->issuer,X509_ATTR_COMMONNAME,&s)) - printf("CN=%.*s ",(int)s.l,s.s); - } - printf("\n"); - - i=lookupoid(oidalg.s,oidalg.l); - if (i!=(size_t)-1) - printf("signature algorithm %s\n",oid2string[i].name); - else { - unsigned long temp[100]; - size_t len=100; - if (scan_asn1rawoid(oidalg.s,oidalg.s+oidalg.l,temp,&len)) { - printf("Unknown signature algorithm (oid "); - for (i=0; i<len; ++i) - printf("%lu%s",temp[i],i+1<len?".":")\n"); - } else - printf("I don't know the algorithm and I can't parse/print the OID\n"); - } - - /* pubkeyalg is a SubjectPublicKeyInfo: - SubjectPublicKeyInfo ::= SEQUENCE{ - algorithm AlgorithmIdentifier, - subjectPublicKey BIT STRING} - - AlgorithmIdentifier ::= SEQUENCE{ - algorithm OBJECT IDENTIFIER, - parameters ANY DEFINED BY algorithm OPTIONAL} - */ - - { - struct string pubkeyoid, pubkeyparams, bits; - if (scan_asn1generic(pubkeyalg.s,pubkeyalg.s+pubkeyalg.l,"{o!}b",&pubkeyoid,&pubkeyparams,&bits)) { - - i=lookupoid(pubkeyoid.s,pubkeyoid.l); - if (i!=(size_t)-1) { - printf("public key algorithm %s\n",oid2string[i].name); - if (oid2string[i].id==X509_ALG_RSA) { - size_t* modulus,* publicExponent; - size_t allocsize=bits.l/8+2*sizeof(modulus[0]); - modulus=malloc(allocsize); - publicExponent=malloc(allocsize); - if (!modulus || !publicExponent) - printf("malloc for RSA bignums failed!\n"); - else { - if (scan_asn1generic(bits.s,bits.s+bits.l/8,"{II}",modulus,publicExponent)) { - if (publicExponent[0]==1) - printf("public exponent %lu\n",publicExponent[1]); - else - printf("public exponent is larger than a word?!\n"); - printf("modulus:\n "); - for (i=1; i<=modulus[0]; ++i) { - size_t j,k; - for (j=0, k=modulus[i]; j<sizeof(modulus[0]); ++j) { - printf("%02lx%s",(k>>((sizeof(modulus[0])*8)-(j+1)*8))&0xff,i==modulus[0] && j==sizeof(modulus[0])-1?"":":"); - } - if ((i-1)%4==3) - if (i==modulus[0]) - printf("\n"); - else - printf("\n "); - } - } else - printf("bignum scanning failed!\n"); - } - free(modulus); free(publicExponent); - } - } else { - unsigned long temp[100]; - size_t len=100; - if (scan_asn1rawoid(pubkeyoid.s,pubkeyoid.s+pubkeyoid.l,temp,&len)) { - printf("Unknown public key algorithm (oid "); - for (i=0; i<len; ++i) - printf("%lu%s",temp[i],i+1<len?".":")\n"); - } else - printf("I don't know the public key algorithm and I can't parse/print the OID\n"); - } - - } else - printf("could not parse public key part!\n"); - - // parse x.509v3 extensions - if (version!=2 && extensions.l) { - printf("Not X.509v3 but extensions present!?\n"); - } else if (extensions.l) { - const char* c=extensions.s; - const char* max=extensions.s+extensions.l; - struct string extoid,extval; - unsigned long noextensions; - if (c!=max) { - size_t n=scan_asn1generic(c,max,"c{!}}!",&noextensions,&extensions,&extval); - if (n==0 || extval.l>0) { - printf("failed to parse X.509v3 extensions!\n"); - c=max; - } else { - c=extensions.s; - max=extensions.s+extensions.l; - } - } - while (c<max) { - size_t n=scan_asn1generic(c,max,"{os}",&extoid,&extval); - if (n) { - size_t i=lookupoid(extoid.s,extoid.l); - if (i!=(size_t)-1) { - printf("X.509 extension %s\n",oid2string[i].name); - } else { - unsigned long temp[100]; - size_t len=100; - if (scan_asn1rawoid(extoid.s,extoid.s+extoid.l,temp,&len)) { - printf("Unknown X.509v3 extension (oid "); - for (i=0; i<len; ++i) - printf("%lu%s",temp[i],i+1<len?".":")\n"); - } else - printf("Failed to parse X.509v3 extension OID\n"); - } - c+=n; - } else { - printf("X.509v3 extension parse error!\n"); - printasn1(c,max); - break; - } - } - } - /* - &extensions, - &oidsig, &sigrest, &sigdata))) { - */ - } - - return n; - - } else { - printasn1(cert,cert+l); - return 0; - } - } - -} - -#include "mmap.h" -#include <stdio.h> - -#include "printasn1.c" - -int main(int argc,char* argv[]) { - char* freewhendone; - const char* buf; - size_t l,n; - struct x509cert c; - struct rsaprivatekey k; - - buf=mmap_read(argc>1?argv[1]:"test.pem",&l); - if (!buf) { puts("test.pem not found"); return 1; } - - n=scan_certificate(buf,l,&c,&freewhendone); - if (!n) - printf("failed to parse certificate\n"); - free(freewhendone); - - buf=mmap_read(argc>2?argv[2]:"privatekey.pem",&l); - if (!buf) { puts("privatekey.pem not found"); return 1; } - - n=scan_rsaprivatekey(buf,l,&k,&freewhendone); - if (!n) - printf("failed to parse rsa private key\n"); - free(freewhendone); - free(k.freewhendone); -} diff --git a/strduptab.c b/strduptab.c deleted file mode 100644 index 07dd244..0000000 --- a/strduptab.c +++ /dev/null @@ -1,30 +0,0 @@ -#include <stdlib.h> -#include "str.h" -#include "strduptab.h" -#include "strstorage.h" -#include "str.h" - -#define PAGESIZE 4096 - -const char* strduptab_add(struct stringduptable* t,const char* s) { - size_t i; - for (i=0; i<t->n; ++i) - if (str_equal(t->s[i],s)) - return t->s[i]; - if (t->n>=t->a) { - const char** x; - int a=t->a*2; - if (!a) a=1024; - if (!(x=realloc((char**)t->s,a*sizeof(char*)))) - return 0; - t->a=a; - t->s=x; - } - { - const char* x=strstorage_add(s,str_len(s)+1); - if (!x) return 0; - s=x; - } - t->s[t->n]=s; ++t->n; - return s; -} diff --git a/strduptab.h b/strduptab.h deleted file mode 100644 index 2bbc67c..0000000 --- a/strduptab.h +++ /dev/null @@ -1,13 +0,0 @@ -/* save memory for constant strings by keeping a list of the ones that - * we already saw and not allocating memory for each new one. The only - * API is "add string and return pointer". Will try to insert the - * string in the table. If the same string was already there, it will - * return a pointer to that string, otherwise it will insert a copy of - * the new string. */ - -struct stringduptable { - size_t n,a; - const char** s; -}; - -const char* strduptab_add(struct stringduptable* t,const char* s); diff --git a/strstorage.c b/strstorage.c deleted file mode 100644 index 3cc98b7..0000000 --- a/strstorage.c +++ /dev/null @@ -1,29 +0,0 @@ -#include <stdlib.h> -#include "byte.h" -#include "strstorage.h" - -#define PAGESIZE 4096 - -const char* strstorage_add(const char* s,size_t n) { - static char* page=0; - static size_t leftonpage=0; - if (leftonpage>=n) { -copyit: - byte_copy(page,n,s); - s=page; - page+=n; - leftonpage-=n; - } else { - if (n>=PAGESIZE/2) { - char* tmp=malloc(n); - if (!tmp) return 0; - byte_copy(tmp,n,s); - s=tmp; - } else { - if (!(page=malloc(PAGESIZE))) return 0; - leftonpage=PAGESIZE; - goto copyit; - } - } - return s; -} diff --git a/strstorage.h b/strstorage.h deleted file mode 100644 index c1837ac..0000000 --- a/strstorage.h +++ /dev/null @@ -1,6 +0,0 @@ -/* provide a string allocator. It is add-only, you can't free a string - * later. On the plus side, the allocation overhead is close to zero. - * Will return a pointer to the stored copy of the string. */ - -const char* strstorage_add(const char* s,size_t n); - |