#include "lib9.h"#include "kernel.h"#include <isa.h>#include "interp.h"#include <mp.h>#include <libsec.h>#include "pool.h"#include "raise.h" /* arguably limbo -t should qualify type name */#define DigestState_copy Keyring_DigestState_copy#define IPint_random Keyring_IPint_random#include "keyringif.h"#include "keyring.h" #include "ipint.h"#include "../libkeyring/keys.h" static Type* TDigestState;static Type* TAESstate;static Type* TDESstate;static Type* TIDEAstate;static Type* TBFstate;static Type* TRC4state; static Type* TSigAlg;static Type* TCertificate;static Type* TSK;static Type* TPK;static Type* TAuthinfo; static Type* TDSAsk;static Type* TDSApk;static Type* TDSAsig;static Type* TEGsk;static Type* TEGpk;static Type* TEGsig;static Type* TRSAsk;static Type* TRSApk;static Type* TRSAsig; enum { Maxmsg= 4096}; static uchar DigestStatemap[] = Keyring_DigestState_map;static uchar AESstatemap[] = Keyring_AESstate_map;static uchar DESstatemap[] = Keyring_DESstate_map;static uchar IDEAstatemap[] = Keyring_IDEAstate_map;static uchar BFstatemap[] = Keyring_BFstate_map;static uchar RC4statemap[] = Keyring_RC4state_map; static uchar SigAlgmap[] = Keyring_SigAlg_map;static uchar SKmap[] = Keyring_SK_map;static uchar PKmap[] = Keyring_PK_map;static uchar Certificatemap[] = Keyring_Certificate_map;static uchar Authinfomap[] = Keyring_Authinfo_map;static uchar DSAskmap[] = Keyring_DSAsk_map;static uchar DSApkmap[] = Keyring_DSApk_map;static uchar DSAsigmap[] = Keyring_DSAsig_map;static uchar EGskmap[] = Keyring_EGsk_map;static uchar EGpkmap[] = Keyring_EGpk_map;static uchar EGsigmap[] = Keyring_EGsig_map;static uchar RSAskmap[] = Keyring_RSAsk_map;static uchar RSApkmap[] = Keyring_RSApk_map;static uchar RSAsigmap[] = Keyring_RSAsig_map; static PK* checkPK(Keyring_PK *k); extern void setid(char*, int);extern vlong osusectime(void);extern void freeIPint(Heap*, int); static char exBadSA[] = "bad signature algorithm";static char exBadSK[] = "bad secret key";static char exBadPK[] = "bad public key";static char exBadCert[] = "bad certificate";static char exBadBsize[] = "data not multiple of block size";static char exBadKey[] = "bad encryption key";static char exBadDigest[] = "bad digest value";static char exBadIvec[] = "bad ivec";static char exBadState[] = "bad encryption state"; typedef struct XBFstate XBFstate; /* BF state */struct XBFstate{ Keyring_BFstate x; BFstate state;}; /* convert a Big to base64 ascii */intbigtobase64(mpint* b, char *buf, int len){ uchar *p; int n, rv, o; n = (b->top+1)*Dbytes; p = malloc(n+1); if(p == nil) goto Err; n = mptobe(b, p+1, n, nil); if(n < 0) goto Err; p[0] = 0; if(n != 0 && (p[1]&0x80)){ /* force leading 0 byte for compatibility with older representation */ /* TO DO: if b->sign < 0, complement bits and add one */ o = 0; n++; }else o = 1; rv = enc64(buf, len, p+o, n); free(p); return rv; Err: free(p); if(len > 0){ *buf = '*'; return 1; } return 0;} /* convert a Big to base64 ascii for %U */intbig64conv(Fmt *f){ mpint *b; char *buf; int n; b = va_arg(f->args, mpint*); n = (b->top+1)*Dbytes + 1; n = ((n+3)/3)*4 + 1; buf = malloc(n); bigtobase64(b, buf, n); n = fmtstrcpy(f, buf); free(buf); return n;} static void*newthing(Type *t, int add){ Heap *h; h = heap(t); if(add) ptradd(h); return H2D(void*, h);} static Keyring_IPint*ipcopymp(mpint* b){ if(b == nil) return H; return newIPint(mpcopy(b));} /* convert a base64 string to a big */mpint*base64tobig(char *str, char **strp){ int n; char *p; mpint *b; uchar hex[(MaxBigBytes*6 + 7)/8]; for(p = str; *p && *p != '\n'; p++) ; if(p == str) return nil; n = dec64(hex, sizeof(hex), str, p - str); b = betomp(hex, n, nil); if(strp){ if(*p) p++; *strp = p; } return b;} /* * signature algorithms */enum{ Maxalg = 8};static SigAlgVec *algs[Maxalg];static int nalg; static SigAlg*newSigAlg(SigAlgVec *vec){ Heap *h; SigAlg *sa; h = heap(TSigAlg); sa = H2D(SigAlg*, h); retstr(vec->name, &sa->x.name); sa->vec = vec; return sa;} static voidfreeSigAlg(Heap *h, int swept){ if(!swept) freeheap(h, 0);} SigAlgVec*findsigalg(char *name){ SigAlgVec **sap; for(sap = algs; sap < &algs[nalg]; sap++) if(strcmp(name, (*sap)->name) == 0) return *sap; return nil;} SigAlg*strtoalg(char *str, char **strp){ int n; char *p, name[20]; SigAlgVec *sa; p = strchr(str, '\n'); if(p == 0){ p = str + strlen(str); if(strp) *strp = p; } else { if(strp) *strp = p+1; } n = p - str; if(n < sizeof(name)){ strncpy(name, str, n); name[n] = 0; sa = findsigalg(name); if(sa != nil) return newSigAlg(sa); } return nil;} static SigAlg*checkSigAlg(Keyring_SigAlg *ksa){ SigAlgVec **sap; SigAlg *sa; sa = (SigAlg*)ksa; for(sap = algs; sap < &algs[Maxalg]; sap++) if(sa->vec == *sap) return sa; errorf("%s: %s", exType, exBadSA); return nil;} /* * parse next new line terminated string into a String */String*strtostring(char *str, char **strp){ char *p; String *s; p = strchr(str, '\n'); if(p == 0) p = str + strlen(str); s = H; retnstr(str, p - str, &s); if(strp){ if(*p) p++; *strp = p; } return s;} /* * private part of a key */static SK*newSK(SigAlg *sa, String *owner, int increfsa){ Heap *h; SK *k; h = heap(TSK); k = H2D(SK*, h); k->x.sa = (Keyring_SigAlg*)sa; if(increfsa) { h = D2H(sa); h->ref++; Setmark(h); } k->x.owner = owner; k->key = 0; return k;} static voidfreeSK(Heap *h, int swept){ SK *k; SigAlg *sa; k = H2D(SK*, h); sa = checkSigAlg(k->x.sa); if(k->key) (*sa->vec->skfree)(k->key); freeheap(h, swept);} static SK*checkSK(Keyring_SK *k){ SK *sk; sk = (SK*)k; if(sk == H || sk == nil || sk->key == 0 || D2H(sk)->t != TSK){ errorf("%s: %s", exType, exBadSK); return nil; } return sk;} voidKeyring_genSK(void *fp){ F_Keyring_genSK *f; SK *sk; SigAlg *sa; void *v; f = fp; v = *f->ret; *f->ret = H; destroy(v); sa = strtoalg(string2c(f->algname), 0); if(sa == nil) return; sk = newSK(sa, stringdup(f->owner), 0); *f->ret = (Keyring_SK*)sk; release(); sk->key = (*sa->vec->gensk)(f->length); acquire();} voidKeyring_genSKfromPK(void *fp){ F_Keyring_genSKfromPK *f; SigAlg *sa; PK *pk; SK *sk; void *v; f = fp; v = *f->ret; *f->ret = H; destroy(v); pk = checkPK(f->pk); sa = checkSigAlg(pk->x.sa); sk = newSK(sa, stringdup(f->owner), 1); *f->ret = (Keyring_SK*)sk; release(); sk->key = (*sa->vec->genskfrompk)(pk->key); acquire();} /* converts a sequence of newline-separated base64-encoded mpints to attr=hexval ... in f */static char*bigs2attr(Fmt *f, char *bigs, char **names){ int i, n, nd; char *b16, *vals[20]; uchar data[(MaxBigBytes*6 + 7)/8]; b16 = malloc(2*MaxBigBytes+1); if(b16 == nil) return nil; n = getfields(bigs, vals, nelem(vals), 0, "\n"); for(i = 0; i < n-1; i++){ if(names == nil || names[i] == nil) break; /* shouldn't happen */ nd = dec64(data, sizeof(data), vals[i], strlen(vals[i])); if(nd < 0) break; enc16(b16, 2*MaxBigBytes+1, data, nd); fmtprint(f, " %s=%s", names[i], b16); } free(b16); return fmtstrflush(f);} voidKeyring_sktoattr(void *fp){ F_Keyring_sktoattr *f; char *val, *buf, *owner; SigAlg *sa; Fmt o; SK *sk; f = fp; sk = checkSK(f->sk); sa = checkSigAlg(sk->x.sa); buf = malloc(Maxbuf); if(buf == nil){ retstr(nil, f->ret); return; } (*sa->vec->sk2str)(sk->key, buf, Maxbuf); fmtstrinit(&o); fmtprint(&o, "alg=%q", string2c(sa->x.name)); owner = string2c(sk->x.owner); if(*owner) fmtprint(&o, " owner=%q", owner); val = bigs2attr(&o, buf, sa->vec->skattr); free(buf); retstr(val, f->ret); free(val);} static intsktostr(SK *sk, char *buf, int len){ int n; SigAlg *sa; sa = checkSigAlg(sk->x.sa); n = snprint(buf, len, "%s\n%s\n", string2c(sa->x.name), string2c(sk->x.owner)); return n + (*sa->vec->sk2str)(sk->key, buf+n, len - n);} voidKeyring_sktostr(void *fp){ F_Keyring_sktostr *f; char *buf; f = fp; buf = malloc(Maxbuf); if(buf) sktostr(checkSK(f->sk), buf, Maxbuf); retstr(buf, f->ret); free(buf);} static SK*strtosk(char *buf){ SK *sk; char *p; SigAlg *sa; String *owner; void *key; sa = strtoalg(buf, &p); if(sa == nil) return H; owner = strtostring(p, &p); if(owner == H){ destroy(sa); return H; } key = (*sa->vec->str2sk)(p, &p); if(key == nil){ destroy(sa); destroy(owner); return H; } sk = newSK(sa, owner, 0); sk->key = key; Lines 1–500 of 3083. Load more
#include "lib9.h" #include "kernel.h" #include <isa.h> #include "interp.h" #include <mp.h> #include <libsec.h> #include "pool.h" #include "raise.h" /* arguably limbo -t should qualify type name */ #define DigestState_copy Keyring_DigestState_copy #define IPint_random Keyring_IPint_random #include "keyringif.h" #include "keyring.h" #include "ipint.h" #include "../libkeyring/keys.h" static Type* TDigestState; static Type* TAESstate; static Type* TDESstate; static Type* TIDEAstate; static Type* TBFstate; static Type* TRC4state; static Type* TSigAlg; static Type* TCertificate; static Type* TSK; static Type* TPK; static Type* TAuthinfo; static Type* TDSAsk; static Type* TDSApk; static Type* TDSAsig; static Type* TEGsk; static Type* TEGpk; static Type* TEGsig; static Type* TRSAsk; static Type* TRSApk; static Type* TRSAsig; enum { Maxmsg= 4096 }; static uchar DigestStatemap[] = Keyring_DigestState_map; static uchar AESstatemap[] = Keyring_AESstate_map; static uchar DESstatemap[] = Keyring_DESstate_map; static uchar IDEAstatemap[] = Keyring_IDEAstate_map; static uchar BFstatemap[] = Keyring_BFstate_map; static uchar RC4statemap[] = Keyring_RC4state_map; static uchar SigAlgmap[] = Keyring_SigAlg_map; static uchar SKmap[] = Keyring_SK_map; static uchar PKmap[] = Keyring_PK_map; static uchar Certificatemap[] = Keyring_Certificate_map; static uchar Authinfomap[] = Keyring_Authinfo_map; static uchar DSAskmap[] = Keyring_DSAsk_map; static uchar DSApkmap[] = Keyring_DSApk_map; static uchar DSAsigmap[] = Keyring_DSAsig_map; static uchar EGskmap[] = Keyring_EGsk_map; static uchar EGpkmap[] = Keyring_EGpk_map; static uchar EGsigmap[] = Keyring_EGsig_map; static uchar RSAskmap[] = Keyring_RSAsk_map; static uchar RSApkmap[] = Keyring_RSApk_map; static uchar RSAsigmap[] = Keyring_RSAsig_map; static PK* checkPK(Keyring_PK *k); extern void setid(char*, int); extern vlong osusectime(void); extern void freeIPint(Heap*, int); static char exBadSA[] = "bad signature algorithm"; static char exBadSK[] = "bad secret key"; static char exBadPK[] = "bad public key"; static char exBadCert[] = "bad certificate"; static char exBadBsize[] = "data not multiple of block size"; static char exBadKey[] = "bad encryption key"; static char exBadDigest[] = "bad digest value"; static char exBadIvec[] = "bad ivec"; static char exBadState[] = "bad encryption state"; typedef struct XBFstate XBFstate; /* BF state */ struct XBFstate { Keyring_BFstate x; BFstate state; }; /* convert a Big to base64 ascii */ int bigtobase64(mpint* b, char *buf, int len) { uchar *p; int n, rv, o; n = (b->top+1)*Dbytes; p = malloc(n+1); if(p == nil) goto Err; n = mptobe(b, p+1, n, nil); if(n < 0) goto Err; p[0] = 0; if(n != 0 && (p[1]&0x80)){ /* force leading 0 byte for compatibility with older representation */ /* TO DO: if b->sign < 0, complement bits and add one */ o = 0; n++; }else o = 1; rv = enc64(buf, len, p+o, n); free(p); return rv; Err: free(p); if(len > 0){ *buf = '*'; return 1; } return 0; } /* convert a Big to base64 ascii for %U */ int big64conv(Fmt *f) { mpint *b; char *buf; int n; b = va_arg(f->args, mpint*); n = (b->top+1)*Dbytes + 1; n = ((n+3)/3)*4 + 1; buf = malloc(n); bigtobase64(b, buf, n); n = fmtstrcpy(f, buf); free(buf); return n; } static void* newthing(Type *t, int add) { Heap *h; h = heap(t); if(add) ptradd(h); return H2D(void*, h); } static Keyring_IPint* ipcopymp(mpint* b) { if(b == nil) return H; return newIPint(mpcopy(b)); } /* convert a base64 string to a big */ mpint* base64tobig(char *str, char **strp) { int n; char *p; mpint *b; uchar hex[(MaxBigBytes*6 + 7)/8]; for(p = str; *p && *p != '\n'; p++) ; if(p == str) return nil; n = dec64(hex, sizeof(hex), str, p - str); b = betomp(hex, n, nil); if(strp){ if(*p) p++; *strp = p; } return b; } /* * signature algorithms */ enum { Maxalg = 8 }; static SigAlgVec *algs[Maxalg]; static int nalg; static SigAlg* newSigAlg(SigAlgVec *vec) { Heap *h; SigAlg *sa; h = heap(TSigAlg); sa = H2D(SigAlg*, h); retstr(vec->name, &sa->x.name); sa->vec = vec; return sa; } static void freeSigAlg(Heap *h, int swept) { if(!swept) freeheap(h, 0); } SigAlgVec* findsigalg(char *name) { SigAlgVec **sap; for(sap = algs; sap < &algs[nalg]; sap++) if(strcmp(name, (*sap)->name) == 0) return *sap; return nil; } SigAlg* strtoalg(char *str, char **strp) { int n; char *p, name[20]; SigAlgVec *sa; p = strchr(str, '\n'); if(p == 0){ p = str + strlen(str); if(strp) *strp = p; } else { if(strp) *strp = p+1; } n = p - str; if(n < sizeof(name)){ strncpy(name, str, n); name[n] = 0; sa = findsigalg(name); if(sa != nil) return newSigAlg(sa); } return nil; } static SigAlg* checkSigAlg(Keyring_SigAlg *ksa) { SigAlgVec **sap; SigAlg *sa; sa = (SigAlg*)ksa; for(sap = algs; sap < &algs[Maxalg]; sap++) if(sa->vec == *sap) return sa; errorf("%s: %s", exType, exBadSA); return nil; } /* * parse next new line terminated string into a String */ String* strtostring(char *str, char **strp) { char *p; String *s; p = strchr(str, '\n'); if(p == 0) p = str + strlen(str); s = H; retnstr(str, p - str, &s); if(strp){ if(*p) p++; *strp = p; } return s; } /* * private part of a key */ static SK* newSK(SigAlg *sa, String *owner, int increfsa) { Heap *h; SK *k; h = heap(TSK); k = H2D(SK*, h); k->x.sa = (Keyring_SigAlg*)sa; if(increfsa) { h = D2H(sa); h->ref++; Setmark(h); } k->x.owner = owner; k->key = 0; return k; } static void freeSK(Heap *h, int swept) { SK *k; SigAlg *sa; k = H2D(SK*, h); sa = checkSigAlg(k->x.sa); if(k->key) (*sa->vec->skfree)(k->key); freeheap(h, swept); } static SK* checkSK(Keyring_SK *k) { SK *sk; sk = (SK*)k; if(sk == H || sk == nil || sk->key == 0 || D2H(sk)->t != TSK){ errorf("%s: %s", exType, exBadSK); return nil; } return sk; } void Keyring_genSK(void *fp) { F_Keyring_genSK *f; SK *sk; SigAlg *sa; void *v; f = fp; v = *f->ret; *f->ret = H; destroy(v); sa = strtoalg(string2c(f->algname), 0); if(sa == nil) return; sk = newSK(sa, stringdup(f->owner), 0); *f->ret = (Keyring_SK*)sk; release(); sk->key = (*sa->vec->gensk)(f->length); acquire(); } void Keyring_genSKfromPK(void *fp) { F_Keyring_genSKfromPK *f; SigAlg *sa; PK *pk; SK *sk; void *v; f = fp; v = *f->ret; *f->ret = H; destroy(v); pk = checkPK(f->pk); sa = checkSigAlg(pk->x.sa); sk = newSK(sa, stringdup(f->owner), 1); *f->ret = (Keyring_SK*)sk; release(); sk->key = (*sa->vec->genskfrompk)(pk->key); acquire(); } /* converts a sequence of newline-separated base64-encoded mpints to attr=hexval ... in f */ static char* bigs2attr(Fmt *f, char *bigs, char **names) { int i, n, nd; char *b16, *vals[20]; uchar data[(MaxBigBytes*6 + 7)/8]; b16 = malloc(2*MaxBigBytes+1); if(b16 == nil) return nil; n = getfields(bigs, vals, nelem(vals), 0, "\n"); for(i = 0; i < n-1; i++){ if(names == nil || names[i] == nil) break; /* shouldn't happen */ nd = dec64(data, sizeof(data), vals[i], strlen(vals[i])); if(nd < 0) break; enc16(b16, 2*MaxBigBytes+1, data, nd); fmtprint(f, " %s=%s", names[i], b16); } free(b16); return fmtstrflush(f); } void Keyring_sktoattr(void *fp) { F_Keyring_sktoattr *f; char *val, *buf, *owner; SigAlg *sa; Fmt o; SK *sk; f = fp; sk = checkSK(f->sk); sa = checkSigAlg(sk->x.sa); buf = malloc(Maxbuf); if(buf == nil){ retstr(nil, f->ret); return; } (*sa->vec->sk2str)(sk->key, buf, Maxbuf); fmtstrinit(&o); fmtprint(&o, "alg=%q", string2c(sa->x.name)); owner = string2c(sk->x.owner); if(*owner) fmtprint(&o, " owner=%q", owner); val = bigs2attr(&o, buf, sa->vec->skattr); free(buf); retstr(val, f->ret); free(val); } static int sktostr(SK *sk, char *buf, int len) { int n; SigAlg *sa; sa = checkSigAlg(sk->x.sa); n = snprint(buf, len, "%s\n%s\n", string2c(sa->x.name), string2c(sk->x.owner)); return n + (*sa->vec->sk2str)(sk->key, buf+n, len - n); } void Keyring_sktostr(void *fp) { F_Keyring_sktostr *f; char *buf; f = fp; buf = malloc(Maxbuf); if(buf) sktostr(checkSK(f->sk), buf, Maxbuf); retstr(buf, f->ret); free(buf); } static SK* strtosk(char *buf) { SK *sk; char *p; SigAlg *sa; String *owner; void *key; sa = strtoalg(buf, &p); if(sa == nil) return H; owner = strtostring(p, &p); if(owner == H){ destroy(sa); return H; } key = (*sa->vec->str2sk)(p, &p); if(key == nil){ destroy(sa); destroy(owner); return H; } sk = newSK(sa, owner, 0); sk->key = key;