137da2899SCharles.Forsyth #include "lib9.h"
237da2899SCharles.Forsyth #include "kernel.h"
337da2899SCharles.Forsyth #include <isa.h>
437da2899SCharles.Forsyth #include "interp.h"
537da2899SCharles.Forsyth #include <mp.h>
637da2899SCharles.Forsyth #include <libsec.h>
737da2899SCharles.Forsyth #include "pool.h"
837da2899SCharles.Forsyth #include "raise.h"
9*7de2b42dSforsyth
10*7de2b42dSforsyth /* arguably limbo -t should qualify type name */
11*7de2b42dSforsyth #define DigestState_copy Keyring_DigestState_copy
12*7de2b42dSforsyth #define IPint_random Keyring_IPint_random
13*7de2b42dSforsyth #include "keyringif.h"
14*7de2b42dSforsyth #include "keyring.h"
15*7de2b42dSforsyth
16*7de2b42dSforsyth #include "ipint.h"
1737da2899SCharles.Forsyth #include "../libkeyring/keys.h"
1837da2899SCharles.Forsyth
19*7de2b42dSforsyth static Type* TDigestState;
20*7de2b42dSforsyth static Type* TAESstate;
21*7de2b42dSforsyth static Type* TDESstate;
22*7de2b42dSforsyth static Type* TIDEAstate;
23*7de2b42dSforsyth static Type* TBFstate;
24*7de2b42dSforsyth static Type* TRC4state;
2537da2899SCharles.Forsyth
26*7de2b42dSforsyth static Type* TSigAlg;
27*7de2b42dSforsyth static Type* TCertificate;
28*7de2b42dSforsyth static Type* TSK;
29*7de2b42dSforsyth static Type* TPK;
30*7de2b42dSforsyth static Type* TAuthinfo;
31*7de2b42dSforsyth
32*7de2b42dSforsyth static Type* TDSAsk;
33*7de2b42dSforsyth static Type* TDSApk;
34*7de2b42dSforsyth static Type* TDSAsig;
35*7de2b42dSforsyth static Type* TEGsk;
36*7de2b42dSforsyth static Type* TEGpk;
37*7de2b42dSforsyth static Type* TEGsig;
38*7de2b42dSforsyth static Type* TRSAsk;
39*7de2b42dSforsyth static Type* TRSApk;
40*7de2b42dSforsyth static Type* TRSAsig;
4137da2899SCharles.Forsyth
4237da2899SCharles.Forsyth enum {
4337da2899SCharles.Forsyth Maxmsg= 4096
4437da2899SCharles.Forsyth };
4537da2899SCharles.Forsyth
46*7de2b42dSforsyth static uchar DigestStatemap[] = Keyring_DigestState_map;
47*7de2b42dSforsyth static uchar AESstatemap[] = Keyring_AESstate_map;
48*7de2b42dSforsyth static uchar DESstatemap[] = Keyring_DESstate_map;
49*7de2b42dSforsyth static uchar IDEAstatemap[] = Keyring_IDEAstate_map;
50*7de2b42dSforsyth static uchar BFstatemap[] = Keyring_BFstate_map;
51*7de2b42dSforsyth static uchar RC4statemap[] = Keyring_RC4state_map;
5237da2899SCharles.Forsyth
53*7de2b42dSforsyth static uchar SigAlgmap[] = Keyring_SigAlg_map;
54*7de2b42dSforsyth static uchar SKmap[] = Keyring_SK_map;
55*7de2b42dSforsyth static uchar PKmap[] = Keyring_PK_map;
56*7de2b42dSforsyth static uchar Certificatemap[] = Keyring_Certificate_map;
57*7de2b42dSforsyth static uchar Authinfomap[] = Keyring_Authinfo_map;
58*7de2b42dSforsyth static uchar DSAskmap[] = Keyring_DSAsk_map;
59*7de2b42dSforsyth static uchar DSApkmap[] = Keyring_DSApk_map;
60*7de2b42dSforsyth static uchar DSAsigmap[] = Keyring_DSAsig_map;
61*7de2b42dSforsyth static uchar EGskmap[] = Keyring_EGsk_map;
62*7de2b42dSforsyth static uchar EGpkmap[] = Keyring_EGpk_map;
63*7de2b42dSforsyth static uchar EGsigmap[] = Keyring_EGsig_map;
64*7de2b42dSforsyth static uchar RSAskmap[] = Keyring_RSAsk_map;
65*7de2b42dSforsyth static uchar RSApkmap[] = Keyring_RSApk_map;
66*7de2b42dSforsyth static uchar RSAsigmap[] = Keyring_RSAsig_map;
67*7de2b42dSforsyth
68*7de2b42dSforsyth static PK* checkPK(Keyring_PK *k);
6937da2899SCharles.Forsyth
7037da2899SCharles.Forsyth extern void setid(char*, int);
7137da2899SCharles.Forsyth extern vlong osusectime(void);
7237da2899SCharles.Forsyth extern void freeIPint(Heap*, int);
7337da2899SCharles.Forsyth
7437da2899SCharles.Forsyth static char exBadSA[] = "bad signature algorithm";
7537da2899SCharles.Forsyth static char exBadSK[] = "bad secret key";
7637da2899SCharles.Forsyth static char exBadPK[] = "bad public key";
7737da2899SCharles.Forsyth static char exBadCert[] = "bad certificate";
78132f29a5Sforsyth static char exBadBsize[] = "data not multiple of block size";
79132f29a5Sforsyth static char exBadKey[] = "bad encryption key";
80132f29a5Sforsyth static char exBadDigest[] = "bad digest value";
81132f29a5Sforsyth static char exBadIvec[] = "bad ivec";
829bca6be9Sforsyth static char exBadState[] = "bad encryption state";
8337da2899SCharles.Forsyth
84ca1042d3SCharles.Forsyth typedef struct XBFstate XBFstate;
85ca1042d3SCharles.Forsyth
86ca1042d3SCharles.Forsyth /* BF state */
87ca1042d3SCharles.Forsyth struct XBFstate
88ca1042d3SCharles.Forsyth {
89ca1042d3SCharles.Forsyth Keyring_BFstate x;
90ca1042d3SCharles.Forsyth BFstate state;
91ca1042d3SCharles.Forsyth };
92ca1042d3SCharles.Forsyth
9337da2899SCharles.Forsyth /* convert a Big to base64 ascii */
9437da2899SCharles.Forsyth int
bigtobase64(mpint * b,char * buf,int len)9531a18a69SCharles.Forsyth bigtobase64(mpint* b, char *buf, int len)
9637da2899SCharles.Forsyth {
9737da2899SCharles.Forsyth uchar *p;
9837da2899SCharles.Forsyth int n, rv, o;
9937da2899SCharles.Forsyth
10037da2899SCharles.Forsyth n = (b->top+1)*Dbytes;
10137da2899SCharles.Forsyth p = malloc(n+1);
10237da2899SCharles.Forsyth if(p == nil)
10337da2899SCharles.Forsyth goto Err;
10437da2899SCharles.Forsyth n = mptobe(b, p+1, n, nil);
10537da2899SCharles.Forsyth if(n < 0)
10637da2899SCharles.Forsyth goto Err;
10737da2899SCharles.Forsyth p[0] = 0;
10837da2899SCharles.Forsyth if(n != 0 && (p[1]&0x80)){
10937da2899SCharles.Forsyth /* force leading 0 byte for compatibility with older representation */
11037da2899SCharles.Forsyth /* TO DO: if b->sign < 0, complement bits and add one */
11137da2899SCharles.Forsyth o = 0;
11237da2899SCharles.Forsyth n++;
11337da2899SCharles.Forsyth }else
11437da2899SCharles.Forsyth o = 1;
11537da2899SCharles.Forsyth rv = enc64(buf, len, p+o, n);
11637da2899SCharles.Forsyth free(p);
11737da2899SCharles.Forsyth return rv;
11837da2899SCharles.Forsyth
11937da2899SCharles.Forsyth Err:
12037da2899SCharles.Forsyth free(p);
12137da2899SCharles.Forsyth if(len > 0){
12237da2899SCharles.Forsyth *buf = '*';
12337da2899SCharles.Forsyth return 1;
12437da2899SCharles.Forsyth }
12537da2899SCharles.Forsyth return 0;
12637da2899SCharles.Forsyth }
12737da2899SCharles.Forsyth
12837da2899SCharles.Forsyth /* convert a Big to base64 ascii for %U */
12937da2899SCharles.Forsyth int
big64conv(Fmt * f)13037da2899SCharles.Forsyth big64conv(Fmt *f)
13137da2899SCharles.Forsyth {
13231a18a69SCharles.Forsyth mpint *b;
13337da2899SCharles.Forsyth char *buf;
13437da2899SCharles.Forsyth int n;
13537da2899SCharles.Forsyth
13631a18a69SCharles.Forsyth b = va_arg(f->args, mpint*);
13737da2899SCharles.Forsyth n = (b->top+1)*Dbytes + 1;
13837da2899SCharles.Forsyth n = ((n+3)/3)*4 + 1;
13937da2899SCharles.Forsyth buf = malloc(n);
14037da2899SCharles.Forsyth bigtobase64(b, buf, n);
14137da2899SCharles.Forsyth n = fmtstrcpy(f, buf);
14237da2899SCharles.Forsyth free(buf);
14337da2899SCharles.Forsyth return n;
14437da2899SCharles.Forsyth }
14537da2899SCharles.Forsyth
146ca1042d3SCharles.Forsyth static void*
newthing(Type * t,int add)147ca1042d3SCharles.Forsyth newthing(Type *t, int add)
148ca1042d3SCharles.Forsyth {
149ca1042d3SCharles.Forsyth Heap *h;
150ca1042d3SCharles.Forsyth
151ca1042d3SCharles.Forsyth h = heap(t);
152ca1042d3SCharles.Forsyth if(add)
153ca1042d3SCharles.Forsyth ptradd(h);
154ca1042d3SCharles.Forsyth return H2D(void*, h);
155ca1042d3SCharles.Forsyth }
156ca1042d3SCharles.Forsyth
157ca1042d3SCharles.Forsyth static Keyring_IPint*
ipcopymp(mpint * b)15831a18a69SCharles.Forsyth ipcopymp(mpint* b)
159ca1042d3SCharles.Forsyth {
160ca1042d3SCharles.Forsyth if(b == nil)
161ca1042d3SCharles.Forsyth return H;
162ca1042d3SCharles.Forsyth return newIPint(mpcopy(b));
163ca1042d3SCharles.Forsyth }
164ca1042d3SCharles.Forsyth
16537da2899SCharles.Forsyth /* convert a base64 string to a big */
16631a18a69SCharles.Forsyth mpint*
base64tobig(char * str,char ** strp)16737da2899SCharles.Forsyth base64tobig(char *str, char **strp)
16837da2899SCharles.Forsyth {
16937da2899SCharles.Forsyth int n;
17037da2899SCharles.Forsyth char *p;
17131a18a69SCharles.Forsyth mpint *b;
17237da2899SCharles.Forsyth uchar hex[(MaxBigBytes*6 + 7)/8];
17337da2899SCharles.Forsyth
17437da2899SCharles.Forsyth for(p = str; *p && *p != '\n'; p++)
17537da2899SCharles.Forsyth ;
176032c0afdSforsyth if(p == str)
177032c0afdSforsyth return nil;
17837da2899SCharles.Forsyth n = dec64(hex, sizeof(hex), str, p - str);
17937da2899SCharles.Forsyth b = betomp(hex, n, nil);
18037da2899SCharles.Forsyth if(strp){
18137da2899SCharles.Forsyth if(*p)
18237da2899SCharles.Forsyth p++;
18337da2899SCharles.Forsyth *strp = p;
18437da2899SCharles.Forsyth }
18537da2899SCharles.Forsyth return b;
18637da2899SCharles.Forsyth }
18737da2899SCharles.Forsyth
18837da2899SCharles.Forsyth /*
18937da2899SCharles.Forsyth * signature algorithms
19037da2899SCharles.Forsyth */
19137da2899SCharles.Forsyth enum
19237da2899SCharles.Forsyth {
19337da2899SCharles.Forsyth Maxalg = 8
19437da2899SCharles.Forsyth };
19537da2899SCharles.Forsyth static SigAlgVec *algs[Maxalg];
19637da2899SCharles.Forsyth static int nalg;
19737da2899SCharles.Forsyth
19837da2899SCharles.Forsyth static SigAlg*
newSigAlg(SigAlgVec * vec)19937da2899SCharles.Forsyth newSigAlg(SigAlgVec *vec)
20037da2899SCharles.Forsyth {
20137da2899SCharles.Forsyth Heap *h;
20237da2899SCharles.Forsyth SigAlg *sa;
20337da2899SCharles.Forsyth
20437da2899SCharles.Forsyth h = heap(TSigAlg);
20537da2899SCharles.Forsyth sa = H2D(SigAlg*, h);
20637da2899SCharles.Forsyth retstr(vec->name, &sa->x.name);
20737da2899SCharles.Forsyth sa->vec = vec;
20837da2899SCharles.Forsyth return sa;
20937da2899SCharles.Forsyth }
21037da2899SCharles.Forsyth
21137da2899SCharles.Forsyth static void
freeSigAlg(Heap * h,int swept)21237da2899SCharles.Forsyth freeSigAlg(Heap *h, int swept)
21337da2899SCharles.Forsyth {
21437da2899SCharles.Forsyth if(!swept)
21537da2899SCharles.Forsyth freeheap(h, 0);
21637da2899SCharles.Forsyth }
21737da2899SCharles.Forsyth
21837da2899SCharles.Forsyth SigAlgVec*
findsigalg(char * name)21937da2899SCharles.Forsyth findsigalg(char *name)
22037da2899SCharles.Forsyth {
22137da2899SCharles.Forsyth SigAlgVec **sap;
22237da2899SCharles.Forsyth
22337da2899SCharles.Forsyth for(sap = algs; sap < &algs[nalg]; sap++)
22437da2899SCharles.Forsyth if(strcmp(name, (*sap)->name) == 0)
22537da2899SCharles.Forsyth return *sap;
22637da2899SCharles.Forsyth return nil;
22737da2899SCharles.Forsyth }
22837da2899SCharles.Forsyth
22937da2899SCharles.Forsyth SigAlg*
strtoalg(char * str,char ** strp)23037da2899SCharles.Forsyth strtoalg(char *str, char **strp)
23137da2899SCharles.Forsyth {
23237da2899SCharles.Forsyth int n;
23337da2899SCharles.Forsyth char *p, name[20];
23437da2899SCharles.Forsyth SigAlgVec *sa;
23537da2899SCharles.Forsyth
23637da2899SCharles.Forsyth
23737da2899SCharles.Forsyth p = strchr(str, '\n');
23837da2899SCharles.Forsyth if(p == 0){
23937da2899SCharles.Forsyth p = str + strlen(str);
24037da2899SCharles.Forsyth if(strp)
24137da2899SCharles.Forsyth *strp = p;
24237da2899SCharles.Forsyth } else {
24337da2899SCharles.Forsyth if(strp)
24437da2899SCharles.Forsyth *strp = p+1;
24537da2899SCharles.Forsyth }
24637da2899SCharles.Forsyth
24737da2899SCharles.Forsyth n = p - str;
24837da2899SCharles.Forsyth if(n < sizeof(name)){
24937da2899SCharles.Forsyth strncpy(name, str, n);
25037da2899SCharles.Forsyth name[n] = 0;
25137da2899SCharles.Forsyth sa = findsigalg(name);
25237da2899SCharles.Forsyth if(sa != nil)
25337da2899SCharles.Forsyth return newSigAlg(sa);
25437da2899SCharles.Forsyth }
25537da2899SCharles.Forsyth return nil;
25637da2899SCharles.Forsyth }
25737da2899SCharles.Forsyth
25837da2899SCharles.Forsyth static SigAlg*
checkSigAlg(Keyring_SigAlg * ksa)25937da2899SCharles.Forsyth checkSigAlg(Keyring_SigAlg *ksa)
26037da2899SCharles.Forsyth {
26137da2899SCharles.Forsyth SigAlgVec **sap;
26237da2899SCharles.Forsyth SigAlg *sa;
26337da2899SCharles.Forsyth
26437da2899SCharles.Forsyth sa = (SigAlg*)ksa;
26537da2899SCharles.Forsyth
26637da2899SCharles.Forsyth for(sap = algs; sap < &algs[Maxalg]; sap++)
26737da2899SCharles.Forsyth if(sa->vec == *sap)
26837da2899SCharles.Forsyth return sa;
26937da2899SCharles.Forsyth errorf("%s: %s", exType, exBadSA);
27037da2899SCharles.Forsyth return nil;
27137da2899SCharles.Forsyth }
27237da2899SCharles.Forsyth
27337da2899SCharles.Forsyth /*
27437da2899SCharles.Forsyth * parse next new line terminated string into a String
27537da2899SCharles.Forsyth */
27637da2899SCharles.Forsyth String*
strtostring(char * str,char ** strp)27737da2899SCharles.Forsyth strtostring(char *str, char **strp)
27837da2899SCharles.Forsyth {
27937da2899SCharles.Forsyth char *p;
28037da2899SCharles.Forsyth String *s;
28137da2899SCharles.Forsyth
28237da2899SCharles.Forsyth p = strchr(str, '\n');
28337da2899SCharles.Forsyth if(p == 0)
28437da2899SCharles.Forsyth p = str + strlen(str);
28537da2899SCharles.Forsyth s = H;
28637da2899SCharles.Forsyth retnstr(str, p - str, &s);
28737da2899SCharles.Forsyth
28837da2899SCharles.Forsyth if(strp){
28937da2899SCharles.Forsyth if(*p)
29037da2899SCharles.Forsyth p++;
29137da2899SCharles.Forsyth *strp = p;
29237da2899SCharles.Forsyth }
29337da2899SCharles.Forsyth
29437da2899SCharles.Forsyth return s;
29537da2899SCharles.Forsyth }
29637da2899SCharles.Forsyth
29737da2899SCharles.Forsyth /*
29837da2899SCharles.Forsyth * private part of a key
29937da2899SCharles.Forsyth */
30037da2899SCharles.Forsyth static SK*
newSK(SigAlg * sa,String * owner,int increfsa)30137da2899SCharles.Forsyth newSK(SigAlg *sa, String *owner, int increfsa)
30237da2899SCharles.Forsyth {
30337da2899SCharles.Forsyth Heap *h;
30437da2899SCharles.Forsyth SK *k;
30537da2899SCharles.Forsyth
30637da2899SCharles.Forsyth h = heap(TSK);
30737da2899SCharles.Forsyth k = H2D(SK*, h);
30837da2899SCharles.Forsyth k->x.sa = (Keyring_SigAlg*)sa;
30937da2899SCharles.Forsyth if(increfsa) {
31037da2899SCharles.Forsyth h = D2H(sa);
31137da2899SCharles.Forsyth h->ref++;
31237da2899SCharles.Forsyth Setmark(h);
31337da2899SCharles.Forsyth }
31437da2899SCharles.Forsyth k->x.owner = owner;
31537da2899SCharles.Forsyth k->key = 0;
31637da2899SCharles.Forsyth return k;
31737da2899SCharles.Forsyth }
31837da2899SCharles.Forsyth
31937da2899SCharles.Forsyth static void
freeSK(Heap * h,int swept)32037da2899SCharles.Forsyth freeSK(Heap *h, int swept)
32137da2899SCharles.Forsyth {
32237da2899SCharles.Forsyth SK *k;
32337da2899SCharles.Forsyth SigAlg *sa;
32437da2899SCharles.Forsyth
32537da2899SCharles.Forsyth k = H2D(SK*, h);
32637da2899SCharles.Forsyth sa = checkSigAlg(k->x.sa);
32737da2899SCharles.Forsyth if(k->key)
32837da2899SCharles.Forsyth (*sa->vec->skfree)(k->key);
32937da2899SCharles.Forsyth freeheap(h, swept);
33037da2899SCharles.Forsyth }
33137da2899SCharles.Forsyth
33237da2899SCharles.Forsyth static SK*
checkSK(Keyring_SK * k)33337da2899SCharles.Forsyth checkSK(Keyring_SK *k)
33437da2899SCharles.Forsyth {
33537da2899SCharles.Forsyth SK *sk;
33637da2899SCharles.Forsyth
33737da2899SCharles.Forsyth sk = (SK*)k;
33837da2899SCharles.Forsyth if(sk == H || sk == nil || sk->key == 0 || D2H(sk)->t != TSK){
33937da2899SCharles.Forsyth errorf("%s: %s", exType, exBadSK);
34037da2899SCharles.Forsyth return nil;
34137da2899SCharles.Forsyth }
34237da2899SCharles.Forsyth return sk;
34337da2899SCharles.Forsyth }
34437da2899SCharles.Forsyth
34537da2899SCharles.Forsyth void
Keyring_genSK(void * fp)34637da2899SCharles.Forsyth Keyring_genSK(void *fp)
34737da2899SCharles.Forsyth {
34837da2899SCharles.Forsyth F_Keyring_genSK *f;
34937da2899SCharles.Forsyth SK *sk;
35037da2899SCharles.Forsyth SigAlg *sa;
35137da2899SCharles.Forsyth void *v;
35237da2899SCharles.Forsyth
35337da2899SCharles.Forsyth f = fp;
35437da2899SCharles.Forsyth v = *f->ret;
35537da2899SCharles.Forsyth *f->ret = H;
35637da2899SCharles.Forsyth destroy(v);
35737da2899SCharles.Forsyth
35837da2899SCharles.Forsyth sa = strtoalg(string2c(f->algname), 0);
35937da2899SCharles.Forsyth if(sa == nil)
36037da2899SCharles.Forsyth return;
36137da2899SCharles.Forsyth
36237da2899SCharles.Forsyth sk = newSK(sa, stringdup(f->owner), 0);
36337da2899SCharles.Forsyth *f->ret = (Keyring_SK*)sk;
36437da2899SCharles.Forsyth release();
36537da2899SCharles.Forsyth sk->key = (*sa->vec->gensk)(f->length);
36637da2899SCharles.Forsyth acquire();
36737da2899SCharles.Forsyth }
36837da2899SCharles.Forsyth
36937da2899SCharles.Forsyth void
Keyring_genSKfromPK(void * fp)37037da2899SCharles.Forsyth Keyring_genSKfromPK(void *fp)
37137da2899SCharles.Forsyth {
37237da2899SCharles.Forsyth F_Keyring_genSKfromPK *f;
37337da2899SCharles.Forsyth SigAlg *sa;
37437da2899SCharles.Forsyth PK *pk;
37537da2899SCharles.Forsyth SK *sk;
37637da2899SCharles.Forsyth void *v;
37737da2899SCharles.Forsyth
37837da2899SCharles.Forsyth f = fp;
37937da2899SCharles.Forsyth v = *f->ret;
38037da2899SCharles.Forsyth *f->ret = H;
38137da2899SCharles.Forsyth destroy(v);
38237da2899SCharles.Forsyth
38337da2899SCharles.Forsyth pk = checkPK(f->pk);
38437da2899SCharles.Forsyth sa = checkSigAlg(pk->x.sa);
38537da2899SCharles.Forsyth sk = newSK(sa, stringdup(f->owner), 1);
38637da2899SCharles.Forsyth *f->ret = (Keyring_SK*)sk;
38737da2899SCharles.Forsyth release();
38837da2899SCharles.Forsyth sk->key = (*sa->vec->genskfrompk)(pk->key);
38937da2899SCharles.Forsyth acquire();
39037da2899SCharles.Forsyth }
39137da2899SCharles.Forsyth
39231a18a69SCharles.Forsyth /* converts a sequence of newline-separated base64-encoded mpints to attr=hexval ... in f */
39337da2899SCharles.Forsyth static char*
bigs2attr(Fmt * f,char * bigs,char ** names)39437da2899SCharles.Forsyth bigs2attr(Fmt *f, char *bigs, char **names)
39537da2899SCharles.Forsyth {
39637da2899SCharles.Forsyth int i, n, nd;
39737da2899SCharles.Forsyth char *b16, *vals[20];
39837da2899SCharles.Forsyth uchar data[(MaxBigBytes*6 + 7)/8];
39937da2899SCharles.Forsyth
40037da2899SCharles.Forsyth b16 = malloc(2*MaxBigBytes+1);
40137da2899SCharles.Forsyth if(b16 == nil)
40237da2899SCharles.Forsyth return nil;
40337da2899SCharles.Forsyth n = getfields(bigs, vals, nelem(vals), 0, "\n");
40437da2899SCharles.Forsyth for(i = 0; i < n-1; i++){
40537da2899SCharles.Forsyth if(names == nil || names[i] == nil)
40637da2899SCharles.Forsyth break; /* shouldn't happen */
40737da2899SCharles.Forsyth nd = dec64(data, sizeof(data), vals[i], strlen(vals[i]));
40837da2899SCharles.Forsyth if(nd < 0)
40937da2899SCharles.Forsyth break;
41037da2899SCharles.Forsyth enc16(b16, 2*MaxBigBytes+1, data, nd);
41137da2899SCharles.Forsyth fmtprint(f, " %s=%s", names[i], b16);
41237da2899SCharles.Forsyth }
41337da2899SCharles.Forsyth free(b16);
41437da2899SCharles.Forsyth return fmtstrflush(f);
41537da2899SCharles.Forsyth }
41637da2899SCharles.Forsyth
41737da2899SCharles.Forsyth void
Keyring_sktoattr(void * fp)41837da2899SCharles.Forsyth Keyring_sktoattr(void *fp)
41937da2899SCharles.Forsyth {
42037da2899SCharles.Forsyth F_Keyring_sktoattr *f;
4212d38c201SCharles.Forsyth char *val, *buf, *owner;
42237da2899SCharles.Forsyth SigAlg *sa;
42337da2899SCharles.Forsyth Fmt o;
42437da2899SCharles.Forsyth SK *sk;
42537da2899SCharles.Forsyth
42637da2899SCharles.Forsyth f = fp;
42737da2899SCharles.Forsyth sk = checkSK(f->sk);
42837da2899SCharles.Forsyth sa = checkSigAlg(sk->x.sa);
42937da2899SCharles.Forsyth buf = malloc(Maxbuf);
43037da2899SCharles.Forsyth if(buf == nil){
43137da2899SCharles.Forsyth retstr(nil, f->ret);
43237da2899SCharles.Forsyth return;
43337da2899SCharles.Forsyth }
43437da2899SCharles.Forsyth (*sa->vec->sk2str)(sk->key, buf, Maxbuf);
43537da2899SCharles.Forsyth fmtstrinit(&o);
4362d38c201SCharles.Forsyth fmtprint(&o, "alg=%q", string2c(sa->x.name));
4372d38c201SCharles.Forsyth owner = string2c(sk->x.owner);
4382d38c201SCharles.Forsyth if(*owner)
4392d38c201SCharles.Forsyth fmtprint(&o, " owner=%q", owner);
44037da2899SCharles.Forsyth val = bigs2attr(&o, buf, sa->vec->skattr);
44137da2899SCharles.Forsyth free(buf);
44237da2899SCharles.Forsyth retstr(val, f->ret);
44337da2899SCharles.Forsyth free(val);
44437da2899SCharles.Forsyth }
44537da2899SCharles.Forsyth
44637da2899SCharles.Forsyth static int
sktostr(SK * sk,char * buf,int len)44737da2899SCharles.Forsyth sktostr(SK *sk, char *buf, int len)
44837da2899SCharles.Forsyth {
44937da2899SCharles.Forsyth int n;
45037da2899SCharles.Forsyth SigAlg *sa;
45137da2899SCharles.Forsyth
45237da2899SCharles.Forsyth sa = checkSigAlg(sk->x.sa);
45337da2899SCharles.Forsyth n = snprint(buf, len, "%s\n%s\n", string2c(sa->x.name),
45437da2899SCharles.Forsyth string2c(sk->x.owner));
45537da2899SCharles.Forsyth return n + (*sa->vec->sk2str)(sk->key, buf+n, len - n);
45637da2899SCharles.Forsyth }
45737da2899SCharles.Forsyth
45837da2899SCharles.Forsyth void
Keyring_sktostr(void * fp)45937da2899SCharles.Forsyth Keyring_sktostr(void *fp)
46037da2899SCharles.Forsyth {
46137da2899SCharles.Forsyth F_Keyring_sktostr *f;
46237da2899SCharles.Forsyth char *buf;
46337da2899SCharles.Forsyth
46437da2899SCharles.Forsyth f = fp;
46537da2899SCharles.Forsyth buf = malloc(Maxbuf);
46637da2899SCharles.Forsyth
46737da2899SCharles.Forsyth if(buf)
46837da2899SCharles.Forsyth sktostr(checkSK(f->sk), buf, Maxbuf);
46937da2899SCharles.Forsyth retstr(buf, f->ret);
47037da2899SCharles.Forsyth
47137da2899SCharles.Forsyth free(buf);
47237da2899SCharles.Forsyth }
47337da2899SCharles.Forsyth
47437da2899SCharles.Forsyth static SK*
strtosk(char * buf)47537da2899SCharles.Forsyth strtosk(char *buf)
47637da2899SCharles.Forsyth {
47737da2899SCharles.Forsyth SK *sk;
47837da2899SCharles.Forsyth char *p;
47937da2899SCharles.Forsyth SigAlg *sa;
48037da2899SCharles.Forsyth String *owner;
48137da2899SCharles.Forsyth void *key;
48237da2899SCharles.Forsyth
48337da2899SCharles.Forsyth sa = strtoalg(buf, &p);
48437da2899SCharles.Forsyth if(sa == nil)
48537da2899SCharles.Forsyth return H;
48637da2899SCharles.Forsyth owner = strtostring(p, &p);
48737da2899SCharles.Forsyth if(owner == H){
48837da2899SCharles.Forsyth destroy(sa);
48937da2899SCharles.Forsyth return H;
49037da2899SCharles.Forsyth }
49137da2899SCharles.Forsyth
49237da2899SCharles.Forsyth key = (*sa->vec->str2sk)(p, &p);
49337da2899SCharles.Forsyth if(key == nil){
49437da2899SCharles.Forsyth destroy(sa);
49537da2899SCharles.Forsyth destroy(owner);
49637da2899SCharles.Forsyth return H;
49737da2899SCharles.Forsyth }
49837da2899SCharles.Forsyth sk = newSK(sa, owner, 0);
49937da2899SCharles.Forsyth sk->key = key;
50037da2899SCharles.Forsyth
50137da2899SCharles.Forsyth return sk;
50237da2899SCharles.Forsyth }
50337da2899SCharles.Forsyth
50437da2899SCharles.Forsyth void
Keyring_strtosk(void * fp)50537da2899SCharles.Forsyth Keyring_strtosk(void *fp)
50637da2899SCharles.Forsyth {
50737da2899SCharles.Forsyth F_Keyring_strtosk *f;
50837da2899SCharles.Forsyth void *v;
50937da2899SCharles.Forsyth
51037da2899SCharles.Forsyth f = fp;
51137da2899SCharles.Forsyth v = *f->ret;
51237da2899SCharles.Forsyth *f->ret = H;
51337da2899SCharles.Forsyth destroy(v);
51437da2899SCharles.Forsyth *f->ret = (Keyring_SK*)strtosk(string2c(f->s));
51537da2899SCharles.Forsyth }
51637da2899SCharles.Forsyth
51737da2899SCharles.Forsyth /*
51837da2899SCharles.Forsyth * public part of a key
51937da2899SCharles.Forsyth */
52037da2899SCharles.Forsyth PK*
newPK(SigAlg * sa,String * owner,int increfsa)52137da2899SCharles.Forsyth newPK(SigAlg *sa, String *owner, int increfsa)
52237da2899SCharles.Forsyth {
52337da2899SCharles.Forsyth Heap *h;
52437da2899SCharles.Forsyth PK *k;
52537da2899SCharles.Forsyth
52637da2899SCharles.Forsyth h = heap(TPK);
52737da2899SCharles.Forsyth k = H2D(PK*, h);
52837da2899SCharles.Forsyth k->x.sa = (Keyring_SigAlg*)sa;
52937da2899SCharles.Forsyth if(increfsa) {
53037da2899SCharles.Forsyth h = D2H(sa);
53137da2899SCharles.Forsyth h->ref++;
53237da2899SCharles.Forsyth Setmark(h);
53337da2899SCharles.Forsyth }
53437da2899SCharles.Forsyth k->x.owner = owner;
53537da2899SCharles.Forsyth k->key = 0;
53637da2899SCharles.Forsyth return k;
53737da2899SCharles.Forsyth }
53837da2899SCharles.Forsyth
53937da2899SCharles.Forsyth void
pkimmutable(PK * k)54037da2899SCharles.Forsyth pkimmutable(PK *k)
54137da2899SCharles.Forsyth {
54237da2899SCharles.Forsyth poolimmutable(D2H(k));
54337da2899SCharles.Forsyth poolimmutable(D2H(k->x.sa));
54437da2899SCharles.Forsyth poolimmutable(D2H(k->x.sa->name));
54537da2899SCharles.Forsyth poolimmutable(D2H(k->x.owner));
54637da2899SCharles.Forsyth }
54737da2899SCharles.Forsyth
54837da2899SCharles.Forsyth void
pkmutable(PK * k)54937da2899SCharles.Forsyth pkmutable(PK *k)
55037da2899SCharles.Forsyth {
55137da2899SCharles.Forsyth poolmutable(D2H(k));
55237da2899SCharles.Forsyth poolmutable(D2H(k->x.sa));
55337da2899SCharles.Forsyth poolmutable(D2H(k->x.sa->name));
55437da2899SCharles.Forsyth poolmutable(D2H(k->x.owner));
55537da2899SCharles.Forsyth }
55637da2899SCharles.Forsyth
55737da2899SCharles.Forsyth void
freePK(Heap * h,int swept)55837da2899SCharles.Forsyth freePK(Heap *h, int swept)
55937da2899SCharles.Forsyth {
56037da2899SCharles.Forsyth PK *k;
56137da2899SCharles.Forsyth SigAlg *sa;
56237da2899SCharles.Forsyth
56337da2899SCharles.Forsyth k = H2D(PK*, h);
56437da2899SCharles.Forsyth sa = checkSigAlg(k->x.sa);
56537da2899SCharles.Forsyth if(k->key)
56637da2899SCharles.Forsyth (*sa->vec->pkfree)(k->key);
56737da2899SCharles.Forsyth freeheap(h, swept);
56837da2899SCharles.Forsyth }
56937da2899SCharles.Forsyth
570*7de2b42dSforsyth static PK*
checkPK(Keyring_PK * k)57137da2899SCharles.Forsyth checkPK(Keyring_PK *k)
57237da2899SCharles.Forsyth {
57337da2899SCharles.Forsyth PK *pk;
57437da2899SCharles.Forsyth
57537da2899SCharles.Forsyth pk = (PK*)k;
57637da2899SCharles.Forsyth if(pk == H || pk == nil || pk->key == 0 || D2H(pk)->t != TPK){
57737da2899SCharles.Forsyth errorf("%s: %s", exType, exBadPK);
57837da2899SCharles.Forsyth return nil;
57937da2899SCharles.Forsyth }
58037da2899SCharles.Forsyth return pk;
58137da2899SCharles.Forsyth }
58237da2899SCharles.Forsyth
58337da2899SCharles.Forsyth void
Keyring_sktopk(void * fp)58437da2899SCharles.Forsyth Keyring_sktopk(void *fp)
58537da2899SCharles.Forsyth {
58637da2899SCharles.Forsyth F_Keyring_sktopk *f;
58737da2899SCharles.Forsyth PK *pk;
58837da2899SCharles.Forsyth SigAlg *sa;
58937da2899SCharles.Forsyth SK *sk;
5909bca6be9Sforsyth void *r;
59137da2899SCharles.Forsyth
59237da2899SCharles.Forsyth f = fp;
5939bca6be9Sforsyth r = *f->ret;
59437da2899SCharles.Forsyth *f->ret = H;
5959bca6be9Sforsyth destroy(r);
59637da2899SCharles.Forsyth
59737da2899SCharles.Forsyth sk = checkSK(f->sk);
59837da2899SCharles.Forsyth sa = checkSigAlg(sk->x.sa);
59937da2899SCharles.Forsyth pk = newPK(sa, stringdup(sk->x.owner), 1);
60037da2899SCharles.Forsyth pk->key = (*sa->vec->sk2pk)(sk->key);
60137da2899SCharles.Forsyth *f->ret = (Keyring_PK*)pk;
60237da2899SCharles.Forsyth }
60337da2899SCharles.Forsyth
60437da2899SCharles.Forsyth static int
pktostr(PK * pk,char * buf,int len)60537da2899SCharles.Forsyth pktostr(PK *pk, char *buf, int len)
60637da2899SCharles.Forsyth {
60737da2899SCharles.Forsyth int n;
60837da2899SCharles.Forsyth SigAlg *sa;
60937da2899SCharles.Forsyth
61037da2899SCharles.Forsyth sa = checkSigAlg(pk->x.sa);
61137da2899SCharles.Forsyth n = snprint(buf, len, "%s\n%s\n", string2c(sa->x.name), string2c(pk->x.owner));
61237da2899SCharles.Forsyth return n + (*sa->vec->pk2str)(pk->key, buf+n, len - n);
61337da2899SCharles.Forsyth }
61437da2899SCharles.Forsyth
61537da2899SCharles.Forsyth void
Keyring_pktostr(void * fp)61637da2899SCharles.Forsyth Keyring_pktostr(void *fp)
61737da2899SCharles.Forsyth {
61837da2899SCharles.Forsyth F_Keyring_pktostr *f;
61937da2899SCharles.Forsyth char *buf;
62037da2899SCharles.Forsyth
62137da2899SCharles.Forsyth f = fp;
62237da2899SCharles.Forsyth buf = malloc(Maxbuf);
62337da2899SCharles.Forsyth
62437da2899SCharles.Forsyth if(buf)
62537da2899SCharles.Forsyth pktostr(checkPK(f->pk), buf, Maxbuf);
62637da2899SCharles.Forsyth retstr(buf, f->ret);
62737da2899SCharles.Forsyth
62837da2899SCharles.Forsyth free(buf);
62937da2899SCharles.Forsyth }
63037da2899SCharles.Forsyth
63137da2899SCharles.Forsyth void
Keyring_pktoattr(void * fp)63237da2899SCharles.Forsyth Keyring_pktoattr(void *fp)
63337da2899SCharles.Forsyth {
63437da2899SCharles.Forsyth F_Keyring_pktoattr *f;
6352d38c201SCharles.Forsyth char *val, *buf, *owner;
63637da2899SCharles.Forsyth SigAlg *sa;
63737da2899SCharles.Forsyth Fmt o;
63837da2899SCharles.Forsyth PK *pk;
63937da2899SCharles.Forsyth
64037da2899SCharles.Forsyth f = fp;
64137da2899SCharles.Forsyth pk = checkPK(f->pk);
64237da2899SCharles.Forsyth sa = checkSigAlg(pk->x.sa);
64337da2899SCharles.Forsyth buf = malloc(Maxbuf);
64437da2899SCharles.Forsyth if(buf == nil){
64537da2899SCharles.Forsyth retstr(nil, f->ret);
64637da2899SCharles.Forsyth return;
64737da2899SCharles.Forsyth }
64837da2899SCharles.Forsyth (*sa->vec->pk2str)(pk->key, buf, Maxbuf);
64937da2899SCharles.Forsyth fmtstrinit(&o);
6502d38c201SCharles.Forsyth fmtprint(&o, "alg=%q", string2c(sa->x.name));
6512d38c201SCharles.Forsyth owner = string2c(pk->x.owner);
6522d38c201SCharles.Forsyth if(*owner)
6532d38c201SCharles.Forsyth fmtprint(&o, " owner=%q", owner);
65437da2899SCharles.Forsyth val = bigs2attr(&o, buf, sa->vec->pkattr);
65537da2899SCharles.Forsyth free(buf);
65637da2899SCharles.Forsyth retstr(val, f->ret);
65737da2899SCharles.Forsyth free(val);
65837da2899SCharles.Forsyth }
65937da2899SCharles.Forsyth
66037da2899SCharles.Forsyth static PK*
strtopk(char * buf)66137da2899SCharles.Forsyth strtopk(char *buf)
66237da2899SCharles.Forsyth {
66337da2899SCharles.Forsyth PK *pk;
66437da2899SCharles.Forsyth char *p;
66537da2899SCharles.Forsyth SigAlg *sa;
66637da2899SCharles.Forsyth String *owner;
66737da2899SCharles.Forsyth void *key;
66837da2899SCharles.Forsyth
66937da2899SCharles.Forsyth sa = strtoalg(buf, &p);
67037da2899SCharles.Forsyth if(sa == nil)
67137da2899SCharles.Forsyth return H;
67237da2899SCharles.Forsyth owner = strtostring(p, &p);
67337da2899SCharles.Forsyth if(owner == H){
67437da2899SCharles.Forsyth destroy(sa);
67537da2899SCharles.Forsyth return H;
67637da2899SCharles.Forsyth }
67737da2899SCharles.Forsyth
67837da2899SCharles.Forsyth key = (*sa->vec->str2pk)(p, &p);
67937da2899SCharles.Forsyth if(key == nil){
68037da2899SCharles.Forsyth destroy(sa);
68137da2899SCharles.Forsyth destroy(owner);
68237da2899SCharles.Forsyth return H;
68337da2899SCharles.Forsyth }
68437da2899SCharles.Forsyth pk = newPK(sa, owner, 0);
68537da2899SCharles.Forsyth pk->key = key;
68637da2899SCharles.Forsyth
68737da2899SCharles.Forsyth return pk;
68837da2899SCharles.Forsyth }
68937da2899SCharles.Forsyth
69037da2899SCharles.Forsyth void
Keyring_strtopk(void * fp)69137da2899SCharles.Forsyth Keyring_strtopk(void *fp)
69237da2899SCharles.Forsyth {
69337da2899SCharles.Forsyth F_Keyring_strtopk *f;
69437da2899SCharles.Forsyth void *v;
69537da2899SCharles.Forsyth
69637da2899SCharles.Forsyth f = fp;
69737da2899SCharles.Forsyth v = *f->ret;
69837da2899SCharles.Forsyth *f->ret = H;
69937da2899SCharles.Forsyth destroy(v);
70037da2899SCharles.Forsyth *f->ret = (Keyring_PK*)strtopk(string2c(f->s));
70137da2899SCharles.Forsyth }
70237da2899SCharles.Forsyth
70337da2899SCharles.Forsyth /*
70437da2899SCharles.Forsyth * Certificates/signatures
70537da2899SCharles.Forsyth */
70637da2899SCharles.Forsyth
70737da2899SCharles.Forsyth void
certimmutable(Certificate * c)70837da2899SCharles.Forsyth certimmutable(Certificate *c)
70937da2899SCharles.Forsyth {
71037da2899SCharles.Forsyth poolimmutable(D2H(c));
71137da2899SCharles.Forsyth poolimmutable(D2H(c->x.signer));
71237da2899SCharles.Forsyth poolimmutable(D2H(c->x.ha));
71337da2899SCharles.Forsyth poolimmutable(D2H(c->x.sa));
71437da2899SCharles.Forsyth poolimmutable(D2H(c->x.sa->name));
71537da2899SCharles.Forsyth }
71637da2899SCharles.Forsyth
71737da2899SCharles.Forsyth void
certmutable(Certificate * c)71837da2899SCharles.Forsyth certmutable(Certificate *c)
71937da2899SCharles.Forsyth {
72037da2899SCharles.Forsyth poolmutable(D2H(c));
72137da2899SCharles.Forsyth poolmutable(D2H(c->x.signer));
72237da2899SCharles.Forsyth poolmutable(D2H(c->x.ha));
72337da2899SCharles.Forsyth Setmark(D2H(c->x.sa));
72437da2899SCharles.Forsyth poolmutable(D2H(c->x.sa));
72537da2899SCharles.Forsyth Setmark(D2H(c->x.sa->name));
72637da2899SCharles.Forsyth poolmutable(D2H(c->x.sa->name));
72737da2899SCharles.Forsyth }
72837da2899SCharles.Forsyth
72937da2899SCharles.Forsyth Certificate*
newCertificate(SigAlg * sa,String * ha,String * signer,long exp,int increfsa)73037da2899SCharles.Forsyth newCertificate(SigAlg *sa, String *ha, String *signer, long exp, int increfsa)
73137da2899SCharles.Forsyth {
73237da2899SCharles.Forsyth Heap *h;
73337da2899SCharles.Forsyth Certificate *c;
73437da2899SCharles.Forsyth
73537da2899SCharles.Forsyth h = heap(TCertificate);
73637da2899SCharles.Forsyth c = H2D(Certificate*, h);
73737da2899SCharles.Forsyth c->x.sa = (Keyring_SigAlg*)sa;
73837da2899SCharles.Forsyth if(increfsa) {
73937da2899SCharles.Forsyth h = D2H(sa);
74037da2899SCharles.Forsyth h->ref++;
74137da2899SCharles.Forsyth Setmark(h);
74237da2899SCharles.Forsyth }
74337da2899SCharles.Forsyth c->x.signer = signer;
74437da2899SCharles.Forsyth c->x.ha = ha;
74537da2899SCharles.Forsyth c->x.exp = exp;
74637da2899SCharles.Forsyth c->signa = 0;
74737da2899SCharles.Forsyth
74837da2899SCharles.Forsyth return c;
74937da2899SCharles.Forsyth }
75037da2899SCharles.Forsyth
75137da2899SCharles.Forsyth void
freeCertificate(Heap * h,int swept)75237da2899SCharles.Forsyth freeCertificate(Heap *h, int swept)
75337da2899SCharles.Forsyth {
75437da2899SCharles.Forsyth Certificate *c;
75537da2899SCharles.Forsyth SigAlg *sa;
75637da2899SCharles.Forsyth
75737da2899SCharles.Forsyth c = H2D(Certificate*, h);
75837da2899SCharles.Forsyth sa = checkSigAlg(c->x.sa);
75937da2899SCharles.Forsyth if(c->signa)
76037da2899SCharles.Forsyth (*sa->vec->sigfree)(c->signa);
76137da2899SCharles.Forsyth freeheap(h, swept);
76237da2899SCharles.Forsyth }
76337da2899SCharles.Forsyth
76437da2899SCharles.Forsyth Certificate*
checkCertificate(Keyring_Certificate * c)76537da2899SCharles.Forsyth checkCertificate(Keyring_Certificate *c)
76637da2899SCharles.Forsyth {
76737da2899SCharles.Forsyth Certificate *cert;
76837da2899SCharles.Forsyth
76937da2899SCharles.Forsyth cert = (Certificate*)c;
77037da2899SCharles.Forsyth if(cert == H || cert == nil || cert->signa == 0 || D2H(cert)->t != TCertificate){
77137da2899SCharles.Forsyth errorf("%s: %s", exType, exBadCert);
77237da2899SCharles.Forsyth return nil;
77337da2899SCharles.Forsyth }
77437da2899SCharles.Forsyth return cert;
77537da2899SCharles.Forsyth }
77637da2899SCharles.Forsyth
77737da2899SCharles.Forsyth static int
certtostr(Certificate * c,char * buf,int len)77837da2899SCharles.Forsyth certtostr(Certificate *c, char *buf, int len)
77937da2899SCharles.Forsyth {
78037da2899SCharles.Forsyth SigAlg *sa;
78137da2899SCharles.Forsyth int n;
78237da2899SCharles.Forsyth
78337da2899SCharles.Forsyth sa = checkSigAlg(c->x.sa);
78437da2899SCharles.Forsyth n = snprint(buf, len, "%s\n%s\n%s\n%d\n", string2c(sa->x.name),
78537da2899SCharles.Forsyth string2c(c->x.ha), string2c(c->x.signer), c->x.exp);
78637da2899SCharles.Forsyth return n + (*sa->vec->sig2str)(c->signa, buf+n, len - n);
78737da2899SCharles.Forsyth }
78837da2899SCharles.Forsyth
78937da2899SCharles.Forsyth void
Keyring_certtostr(void * fp)79037da2899SCharles.Forsyth Keyring_certtostr(void *fp)
79137da2899SCharles.Forsyth {
79237da2899SCharles.Forsyth F_Keyring_certtostr *f;
79337da2899SCharles.Forsyth char *buf;
79437da2899SCharles.Forsyth
79537da2899SCharles.Forsyth f = fp;
79637da2899SCharles.Forsyth buf = malloc(Maxbuf);
79737da2899SCharles.Forsyth
79837da2899SCharles.Forsyth if(buf)
79937da2899SCharles.Forsyth certtostr(checkCertificate(f->c), buf, Maxbuf);
80037da2899SCharles.Forsyth retstr(buf, f->ret);
80137da2899SCharles.Forsyth
80237da2899SCharles.Forsyth free(buf);
80337da2899SCharles.Forsyth }
80437da2899SCharles.Forsyth
80537da2899SCharles.Forsyth void
Keyring_certtoattr(void * fp)80637da2899SCharles.Forsyth Keyring_certtoattr(void *fp)
80737da2899SCharles.Forsyth {
80837da2899SCharles.Forsyth F_Keyring_certtoattr *f;
80937da2899SCharles.Forsyth char *val, *buf, *ha;
81037da2899SCharles.Forsyth SigAlg *sa;
81137da2899SCharles.Forsyth Fmt o;
81237da2899SCharles.Forsyth Certificate *c;
81337da2899SCharles.Forsyth
81437da2899SCharles.Forsyth f = fp;
81537da2899SCharles.Forsyth c = checkCertificate(f->c);
81637da2899SCharles.Forsyth sa = checkSigAlg(c->x.sa);
81737da2899SCharles.Forsyth buf = malloc(Maxbuf);
81837da2899SCharles.Forsyth if(buf == nil){
81937da2899SCharles.Forsyth retstr(nil, f->ret);
82037da2899SCharles.Forsyth return;
82137da2899SCharles.Forsyth }
82237da2899SCharles.Forsyth (*sa->vec->sig2str)(c->signa, buf, Maxbuf);
82337da2899SCharles.Forsyth ha = string2c(c->x.ha);
82437da2899SCharles.Forsyth if(strcmp(ha, "sha") == 0)
82537da2899SCharles.Forsyth ha = "sha1"; /* normalise */
82637da2899SCharles.Forsyth fmtstrinit(&o);
82737da2899SCharles.Forsyth fmtprint(&o, "sigalg=%q-%q signer=%q expires=%ud", string2c(sa->x.name), ha,
82837da2899SCharles.Forsyth string2c(c->x.signer), c->x.exp);
82937da2899SCharles.Forsyth val = bigs2attr(&o, buf, sa->vec->sigattr);
83037da2899SCharles.Forsyth free(buf);
83137da2899SCharles.Forsyth retstr(val, f->ret);
83237da2899SCharles.Forsyth free(val);
83337da2899SCharles.Forsyth }
83437da2899SCharles.Forsyth
83537da2899SCharles.Forsyth static Certificate*
strtocert(char * buf)83637da2899SCharles.Forsyth strtocert(char *buf)
83737da2899SCharles.Forsyth {
83837da2899SCharles.Forsyth Certificate *c;
83937da2899SCharles.Forsyth char *p;
84037da2899SCharles.Forsyth SigAlg *sa;
84137da2899SCharles.Forsyth String *signer, *ha;
84237da2899SCharles.Forsyth long exp;
84337da2899SCharles.Forsyth void *signa;
84437da2899SCharles.Forsyth
84537da2899SCharles.Forsyth sa = strtoalg(buf, &p);
84637da2899SCharles.Forsyth if(sa == 0)
84737da2899SCharles.Forsyth return H;
84837da2899SCharles.Forsyth
84937da2899SCharles.Forsyth ha = strtostring(p, &p);
85037da2899SCharles.Forsyth if(ha == H){
85137da2899SCharles.Forsyth destroy(sa);
85237da2899SCharles.Forsyth return H;
85337da2899SCharles.Forsyth }
85437da2899SCharles.Forsyth
85537da2899SCharles.Forsyth signer = strtostring(p, &p);
85637da2899SCharles.Forsyth if(signer == H){
85737da2899SCharles.Forsyth destroy(sa);
85837da2899SCharles.Forsyth destroy(ha);
85937da2899SCharles.Forsyth return H;
86037da2899SCharles.Forsyth }
86137da2899SCharles.Forsyth
86237da2899SCharles.Forsyth exp = strtoul(p, &p, 10);
86337da2899SCharles.Forsyth if(*p)
86437da2899SCharles.Forsyth p++;
86537da2899SCharles.Forsyth signa = (*sa->vec->str2sig)(p, &p);
86637da2899SCharles.Forsyth if(signa == nil){
86737da2899SCharles.Forsyth destroy(sa);
86837da2899SCharles.Forsyth destroy(ha);
86937da2899SCharles.Forsyth destroy(signer);
87037da2899SCharles.Forsyth return H;
87137da2899SCharles.Forsyth }
87237da2899SCharles.Forsyth
87337da2899SCharles.Forsyth c = newCertificate(sa, ha, signer, exp, 0);
87437da2899SCharles.Forsyth c->signa = signa;
87537da2899SCharles.Forsyth
87637da2899SCharles.Forsyth return c;
87737da2899SCharles.Forsyth }
87837da2899SCharles.Forsyth
87937da2899SCharles.Forsyth void
Keyring_strtocert(void * fp)88037da2899SCharles.Forsyth Keyring_strtocert(void *fp)
88137da2899SCharles.Forsyth {
88237da2899SCharles.Forsyth F_Keyring_strtocert *f;
8839bca6be9Sforsyth void *r;
88437da2899SCharles.Forsyth
88537da2899SCharles.Forsyth f = fp;
8869bca6be9Sforsyth r = *f->ret;
88737da2899SCharles.Forsyth *f->ret = H;
8889bca6be9Sforsyth destroy(r);
88937da2899SCharles.Forsyth *f->ret = (Keyring_Certificate*)strtocert(string2c(f->s));
89037da2899SCharles.Forsyth }
89137da2899SCharles.Forsyth
89237da2899SCharles.Forsyth static Certificate*
sign(SK * sk,char * ha,ulong exp,uchar * a,int len)89337da2899SCharles.Forsyth sign(SK *sk, char *ha, ulong exp, uchar *a, int len)
89437da2899SCharles.Forsyth {
89537da2899SCharles.Forsyth Certificate *c;
89631a18a69SCharles.Forsyth mpint *b;
89737da2899SCharles.Forsyth int n;
89837da2899SCharles.Forsyth SigAlg *sa;
89937da2899SCharles.Forsyth DigestState *ds;
90037da2899SCharles.Forsyth uchar digest[SHA1dlen];
90137da2899SCharles.Forsyth char *buf;
90237da2899SCharles.Forsyth String *hastr;
90337da2899SCharles.Forsyth
90437da2899SCharles.Forsyth hastr = H;
90537da2899SCharles.Forsyth sa = checkSigAlg(sk->x.sa);
90637da2899SCharles.Forsyth buf = malloc(Maxbuf);
90737da2899SCharles.Forsyth if(buf == nil)
90837da2899SCharles.Forsyth return nil;
90937da2899SCharles.Forsyth
91037da2899SCharles.Forsyth /* add signer name and expiration time to hash */
91137da2899SCharles.Forsyth n = snprint(buf, Maxbuf, "%s %lud", string2c(sk->x.owner), exp);
91237da2899SCharles.Forsyth if(strcmp(ha, "sha") == 0 || strcmp(ha, "sha1") == 0){
91337da2899SCharles.Forsyth ds = sha1(a, len, 0, 0);
91437da2899SCharles.Forsyth sha1((uchar*)buf, n, digest, ds);
91537da2899SCharles.Forsyth n = Keyring_SHA1dlen;
91637da2899SCharles.Forsyth } else if(strcmp(ha, "md5") == 0){
91737da2899SCharles.Forsyth ds = md5(a, len, 0, 0);
91837da2899SCharles.Forsyth md5((uchar*)buf, n, digest, ds);
91937da2899SCharles.Forsyth n = Keyring_MD5dlen;
92037da2899SCharles.Forsyth } else if(strcmp(ha, "md4") == 0){
92137da2899SCharles.Forsyth ds = md4(a, len, 0, 0);
92237da2899SCharles.Forsyth md4((uchar*)buf, n, digest, ds);
92337da2899SCharles.Forsyth n = Keyring_MD5dlen;
92437da2899SCharles.Forsyth } else {
92537da2899SCharles.Forsyth free(buf);
92637da2899SCharles.Forsyth return nil;
92737da2899SCharles.Forsyth }
92837da2899SCharles.Forsyth free(buf);
92937da2899SCharles.Forsyth
93037da2899SCharles.Forsyth /* turn message into a big integer */
93137da2899SCharles.Forsyth b = betomp(digest, n, nil);
93237da2899SCharles.Forsyth if(b == nil)
93337da2899SCharles.Forsyth return nil;
93437da2899SCharles.Forsyth
93537da2899SCharles.Forsyth /* sign */
93637da2899SCharles.Forsyth retstr(ha, &hastr);
93737da2899SCharles.Forsyth c = newCertificate(sa, hastr, stringdup(sk->x.owner), exp, 1);
93837da2899SCharles.Forsyth certimmutable(c); /* hide from the garbage collector */
93937da2899SCharles.Forsyth release();
94037da2899SCharles.Forsyth c->signa = (*sa->vec->sign)(b, sk->key);
94137da2899SCharles.Forsyth acquire();
94237da2899SCharles.Forsyth mpfree(b);
94337da2899SCharles.Forsyth
94437da2899SCharles.Forsyth return c;
94537da2899SCharles.Forsyth }
94637da2899SCharles.Forsyth
94737da2899SCharles.Forsyth void
Keyring_sign(void * fp)94837da2899SCharles.Forsyth Keyring_sign(void *fp)
94937da2899SCharles.Forsyth {
95037da2899SCharles.Forsyth F_Keyring_sign *f;
95137da2899SCharles.Forsyth Certificate *c;
95231a18a69SCharles.Forsyth mpint *b;
95337da2899SCharles.Forsyth int n;
95437da2899SCharles.Forsyth SigAlg *sa;
95537da2899SCharles.Forsyth SK *sk;
95637da2899SCharles.Forsyth XDigestState *ds;
95737da2899SCharles.Forsyth uchar digest[SHA1dlen];
95837da2899SCharles.Forsyth char *buf;
95937da2899SCharles.Forsyth void *v;
96037da2899SCharles.Forsyth
96137da2899SCharles.Forsyth f = fp;
96237da2899SCharles.Forsyth v = *f->ret;
96337da2899SCharles.Forsyth *f->ret = H;
96437da2899SCharles.Forsyth destroy(v);
96537da2899SCharles.Forsyth
96637da2899SCharles.Forsyth sk = checkSK(f->sk);
96737da2899SCharles.Forsyth sa = checkSigAlg(sk->x.sa);
96837da2899SCharles.Forsyth
96937da2899SCharles.Forsyth /* add signer name and expiration time to hash */
97037da2899SCharles.Forsyth if(f->state == H)
97137da2899SCharles.Forsyth return;
97237da2899SCharles.Forsyth buf = malloc(Maxbuf);
97337da2899SCharles.Forsyth if(buf == nil)
97437da2899SCharles.Forsyth return;
97537da2899SCharles.Forsyth ds = (XDigestState*)f->state;
97637da2899SCharles.Forsyth n = snprint(buf, Maxbuf, "%s %d", string2c(sk->x.owner), f->exp);
97737da2899SCharles.Forsyth if(strcmp(string2c(f->ha), "sha") == 0 || strcmp(string2c(f->ha), "sha1") == 0){
97837da2899SCharles.Forsyth sha1((uchar*)buf, n, digest, &ds->state);
97937da2899SCharles.Forsyth n = Keyring_SHA1dlen;
98037da2899SCharles.Forsyth } else if(strcmp(string2c(f->ha), "md5") == 0){
98137da2899SCharles.Forsyth md5((uchar*)buf, n, digest, &ds->state);
98237da2899SCharles.Forsyth n = Keyring_MD5dlen;
98337da2899SCharles.Forsyth } else if(strcmp(string2c(f->ha), "md4") == 0){
98437da2899SCharles.Forsyth md4((uchar*)buf, n, digest, &ds->state);
98537da2899SCharles.Forsyth n = Keyring_MD5dlen;
98637da2899SCharles.Forsyth } else {
98737da2899SCharles.Forsyth free(buf);
98837da2899SCharles.Forsyth return;
98937da2899SCharles.Forsyth }
99037da2899SCharles.Forsyth free(buf);
99137da2899SCharles.Forsyth
99237da2899SCharles.Forsyth /* turn message into a big integer */
99337da2899SCharles.Forsyth b = betomp(digest, n, nil);
99437da2899SCharles.Forsyth if(b == nil)
99537da2899SCharles.Forsyth return;
99637da2899SCharles.Forsyth
99737da2899SCharles.Forsyth /* sign */
99837da2899SCharles.Forsyth c = newCertificate(sa, stringdup(f->ha), stringdup(sk->x.owner), f->exp, 1);
99937da2899SCharles.Forsyth *f->ret = (Keyring_Certificate*)c;
100037da2899SCharles.Forsyth release();
100137da2899SCharles.Forsyth c->signa = (*sa->vec->sign)(b, sk->key);
100237da2899SCharles.Forsyth acquire();
100337da2899SCharles.Forsyth mpfree(b);
100437da2899SCharles.Forsyth }
100537da2899SCharles.Forsyth
100637da2899SCharles.Forsyth void
Keyring_signm(void * fp)100737da2899SCharles.Forsyth Keyring_signm(void *fp)
100837da2899SCharles.Forsyth {
100937da2899SCharles.Forsyth F_Keyring_signm *f;
101037da2899SCharles.Forsyth Certificate *c;
101131a18a69SCharles.Forsyth mpint *b;
101237da2899SCharles.Forsyth SigAlg *sa;
101337da2899SCharles.Forsyth SK *sk;
101437da2899SCharles.Forsyth void *v;
101537da2899SCharles.Forsyth
101637da2899SCharles.Forsyth f = fp;
101737da2899SCharles.Forsyth v = *f->ret;
101837da2899SCharles.Forsyth *f->ret = H;
101937da2899SCharles.Forsyth destroy(v);
102037da2899SCharles.Forsyth
102137da2899SCharles.Forsyth sk = checkSK(f->sk);
102237da2899SCharles.Forsyth sa = checkSigAlg(sk->x.sa);
102337da2899SCharles.Forsyth
102437da2899SCharles.Forsyth if(f->m == H)
102537da2899SCharles.Forsyth return;
102637da2899SCharles.Forsyth b = checkIPint(f->m);
102737da2899SCharles.Forsyth
102837da2899SCharles.Forsyth /* sign */
102937da2899SCharles.Forsyth c = newCertificate(sa, stringdup(f->ha), stringdup(sk->x.owner), 0, 1);
103037da2899SCharles.Forsyth *f->ret = (Keyring_Certificate*)c;
103137da2899SCharles.Forsyth release();
103237da2899SCharles.Forsyth c->signa = (*sa->vec->sign)(b, sk->key);
103337da2899SCharles.Forsyth acquire();
103437da2899SCharles.Forsyth }
103537da2899SCharles.Forsyth
103637da2899SCharles.Forsyth static int
verify(PK * pk,Certificate * c,char * a,int len)103737da2899SCharles.Forsyth verify(PK *pk, Certificate *c, char *a, int len)
103837da2899SCharles.Forsyth {
103931a18a69SCharles.Forsyth mpint *b;
104037da2899SCharles.Forsyth int n;
104137da2899SCharles.Forsyth SigAlg *sa, *pksa;
104237da2899SCharles.Forsyth DigestState *ds;
104337da2899SCharles.Forsyth uchar digest[SHA1dlen];
104437da2899SCharles.Forsyth char *buf;
104537da2899SCharles.Forsyth
104637da2899SCharles.Forsyth sa = checkSigAlg(c->x.sa);
104737da2899SCharles.Forsyth pksa = checkSigAlg(pk->x.sa);
104837da2899SCharles.Forsyth if(sa->vec != pksa->vec)
104937da2899SCharles.Forsyth return 0;
105037da2899SCharles.Forsyth
105137da2899SCharles.Forsyth /* add signer name and expiration time to hash */
105237da2899SCharles.Forsyth buf = malloc(Maxbuf);
105337da2899SCharles.Forsyth if(buf == nil)
105437da2899SCharles.Forsyth return 0;
105537da2899SCharles.Forsyth n = snprint(buf, Maxbuf, "%s %d", string2c(c->x.signer), c->x.exp);
105637da2899SCharles.Forsyth if(strcmp(string2c(c->x.ha), "sha") == 0 || strcmp(string2c(c->x.ha), "sha1") == 0){
105737da2899SCharles.Forsyth ds = sha1((uchar*)a, len, 0, 0);
105837da2899SCharles.Forsyth sha1((uchar*)buf, n, digest, ds);
105937da2899SCharles.Forsyth n = Keyring_SHA1dlen;
106037da2899SCharles.Forsyth } else if(strcmp(string2c(c->x.ha), "md5") == 0){
106137da2899SCharles.Forsyth ds = md5((uchar*)a, len, 0, 0);
106237da2899SCharles.Forsyth md5((uchar*)buf, n, digest, ds);
106337da2899SCharles.Forsyth n = Keyring_MD5dlen;
106437da2899SCharles.Forsyth } else if(strcmp(string2c(c->x.ha), "md4") == 0){
106537da2899SCharles.Forsyth ds = md4((uchar*)a, len, 0, 0);
106637da2899SCharles.Forsyth md4((uchar*)buf, n, digest, ds);
106737da2899SCharles.Forsyth n = Keyring_MD5dlen;
106837da2899SCharles.Forsyth } else {
106937da2899SCharles.Forsyth free(buf);
107037da2899SCharles.Forsyth return 0;
107137da2899SCharles.Forsyth }
107237da2899SCharles.Forsyth free(buf);
107337da2899SCharles.Forsyth
107437da2899SCharles.Forsyth /* turn message into a big integer */
107537da2899SCharles.Forsyth b = betomp(digest, n, nil);
107637da2899SCharles.Forsyth if(b == nil)
107737da2899SCharles.Forsyth return 0;
107837da2899SCharles.Forsyth /* verify */
107937da2899SCharles.Forsyth release();
108037da2899SCharles.Forsyth n = (*sa->vec->verify)(b, c->signa, pk->key);
108137da2899SCharles.Forsyth acquire();
108237da2899SCharles.Forsyth
108337da2899SCharles.Forsyth mpfree(b);
108437da2899SCharles.Forsyth return n;
108537da2899SCharles.Forsyth }
108637da2899SCharles.Forsyth
108737da2899SCharles.Forsyth void
Keyring_verify(void * fp)108837da2899SCharles.Forsyth Keyring_verify(void *fp)
108937da2899SCharles.Forsyth {
109037da2899SCharles.Forsyth F_Keyring_verify *f;
109137da2899SCharles.Forsyth Certificate *c;
109231a18a69SCharles.Forsyth mpint *b;
109337da2899SCharles.Forsyth int n;
109437da2899SCharles.Forsyth SigAlg *sa, *pksa;
109537da2899SCharles.Forsyth PK *pk;
109637da2899SCharles.Forsyth XDigestState *ds;
109737da2899SCharles.Forsyth uchar digest[SHA1dlen];
109837da2899SCharles.Forsyth char *buf;
109937da2899SCharles.Forsyth
110037da2899SCharles.Forsyth f = fp;
110137da2899SCharles.Forsyth *f->ret = 0;
110237da2899SCharles.Forsyth
110337da2899SCharles.Forsyth c = checkCertificate(f->cert);
110437da2899SCharles.Forsyth sa = checkSigAlg(c->x.sa);
110537da2899SCharles.Forsyth pk = checkPK(f->pk);
110637da2899SCharles.Forsyth pksa = checkSigAlg(pk->x.sa);
110737da2899SCharles.Forsyth if(sa->vec != pksa->vec)
110837da2899SCharles.Forsyth return;
110937da2899SCharles.Forsyth
111037da2899SCharles.Forsyth /* add signer name and expiration time to hash */
111137da2899SCharles.Forsyth if(f->state == H)
111237da2899SCharles.Forsyth return;
111337da2899SCharles.Forsyth buf = malloc(Maxbuf);
111437da2899SCharles.Forsyth if(buf == nil)
111537da2899SCharles.Forsyth return;
111637da2899SCharles.Forsyth n = snprint(buf, Maxbuf, "%s %d", string2c(c->x.signer), c->x.exp);
111737da2899SCharles.Forsyth ds = (XDigestState*)f->state;
111837da2899SCharles.Forsyth
111937da2899SCharles.Forsyth if(strcmp(string2c(c->x.ha), "sha") == 0 || strcmp(string2c(c->x.ha), "sha1") == 0){
112037da2899SCharles.Forsyth sha1((uchar*)buf, n, digest, &ds->state);
112137da2899SCharles.Forsyth n = Keyring_SHA1dlen;
112237da2899SCharles.Forsyth } else if(strcmp(string2c(c->x.ha), "md5") == 0){
112337da2899SCharles.Forsyth md5((uchar*)buf, n, digest, &ds->state);
112437da2899SCharles.Forsyth n = Keyring_MD5dlen;
112537da2899SCharles.Forsyth } else if(strcmp(string2c(c->x.ha), "md4") == 0){
112637da2899SCharles.Forsyth md4((uchar*)buf, n, digest, &ds->state);
112737da2899SCharles.Forsyth n = Keyring_MD5dlen;
112837da2899SCharles.Forsyth } else {
112937da2899SCharles.Forsyth free(buf);
113037da2899SCharles.Forsyth return;
113137da2899SCharles.Forsyth }
113237da2899SCharles.Forsyth free(buf);
113337da2899SCharles.Forsyth
113437da2899SCharles.Forsyth /* turn message into a big integer */
113537da2899SCharles.Forsyth b = betomp(digest, n, nil);
113637da2899SCharles.Forsyth if(b == nil)
113737da2899SCharles.Forsyth return;
113837da2899SCharles.Forsyth
113937da2899SCharles.Forsyth /* verify */
114037da2899SCharles.Forsyth release();
114137da2899SCharles.Forsyth *f->ret = (*sa->vec->verify)(b, c->signa, pk->key);
114237da2899SCharles.Forsyth acquire();
114337da2899SCharles.Forsyth
114437da2899SCharles.Forsyth mpfree(b);
114537da2899SCharles.Forsyth }
114637da2899SCharles.Forsyth
114737da2899SCharles.Forsyth void
Keyring_verifym(void * fp)114837da2899SCharles.Forsyth Keyring_verifym(void *fp)
114937da2899SCharles.Forsyth {
115037da2899SCharles.Forsyth F_Keyring_verifym *f;
115137da2899SCharles.Forsyth Certificate *c;
115237da2899SCharles.Forsyth SigAlg *sa, *pksa;
115337da2899SCharles.Forsyth PK *pk;
115437da2899SCharles.Forsyth
115537da2899SCharles.Forsyth f = fp;
115637da2899SCharles.Forsyth *f->ret = 0;
115737da2899SCharles.Forsyth
115837da2899SCharles.Forsyth c = checkCertificate(f->cert);
115937da2899SCharles.Forsyth sa = checkSigAlg(c->x.sa);
116037da2899SCharles.Forsyth pk = checkPK(f->pk);
116137da2899SCharles.Forsyth pksa = checkSigAlg(pk->x.sa);
116237da2899SCharles.Forsyth if(sa->vec != pksa->vec)
116337da2899SCharles.Forsyth return;
116437da2899SCharles.Forsyth
116537da2899SCharles.Forsyth if(f->m == H)
116637da2899SCharles.Forsyth return;
116737da2899SCharles.Forsyth
116837da2899SCharles.Forsyth release();
116937da2899SCharles.Forsyth *f->ret = (*sa->vec->verify)(checkIPint(f->m), c->signa, pk->key);
117037da2899SCharles.Forsyth acquire();
117137da2899SCharles.Forsyth }
117237da2899SCharles.Forsyth
117337da2899SCharles.Forsyth /*
117437da2899SCharles.Forsyth * digests
117537da2899SCharles.Forsyth */
117637da2899SCharles.Forsyth void
Keyring_DigestState_copy(void * fp)1177*7de2b42dSforsyth Keyring_DigestState_copy(void *fp)
117837da2899SCharles.Forsyth {
117937da2899SCharles.Forsyth F_DigestState_copy *f;
118037da2899SCharles.Forsyth Heap *h;
11819bca6be9Sforsyth XDigestState *ds, *ods;
118237da2899SCharles.Forsyth void *r;
118337da2899SCharles.Forsyth
118437da2899SCharles.Forsyth f = fp;
118537da2899SCharles.Forsyth r = *f->ret;
118637da2899SCharles.Forsyth *f->ret = H;
118737da2899SCharles.Forsyth destroy(r);
118837da2899SCharles.Forsyth
118937da2899SCharles.Forsyth if(f->d != H){
11909bca6be9Sforsyth ods = checktype(f->d, TDigestState, "DigestState", 0);
119137da2899SCharles.Forsyth h = heap(TDigestState);
119237da2899SCharles.Forsyth ds = H2D(XDigestState*, h);
11939bca6be9Sforsyth memmove(&ds->state, &ods->state, sizeof(ds->state));
119437da2899SCharles.Forsyth *f->ret = (Keyring_DigestState*)ds;
119537da2899SCharles.Forsyth }
119637da2899SCharles.Forsyth }
119737da2899SCharles.Forsyth
119837da2899SCharles.Forsyth static Keyring_DigestState*
keyring_digest_x(Array * buf,int n,Array * digest,int dlen,Keyring_DigestState * state,DigestState * (* fn)(uchar *,ulong,uchar *,DigestState *))119937da2899SCharles.Forsyth keyring_digest_x(Array *buf, int n, Array *digest, int dlen, Keyring_DigestState *state, DigestState* (*fn)(uchar*, ulong, uchar*, DigestState*))
120037da2899SCharles.Forsyth {
120137da2899SCharles.Forsyth Heap *h;
120237da2899SCharles.Forsyth XDigestState *ds;
120337da2899SCharles.Forsyth uchar *cbuf, *cdigest;
120437da2899SCharles.Forsyth
120537da2899SCharles.Forsyth if(buf != H){
120637da2899SCharles.Forsyth if(n > buf->len)
120737da2899SCharles.Forsyth n = buf->len;
120837da2899SCharles.Forsyth cbuf = buf->data;
120937da2899SCharles.Forsyth }else{
121037da2899SCharles.Forsyth if(n != 0)
1211132f29a5Sforsyth error(exInval);
121237da2899SCharles.Forsyth cbuf = nil;
121337da2899SCharles.Forsyth }
121437da2899SCharles.Forsyth
121537da2899SCharles.Forsyth if(digest != H){
121637da2899SCharles.Forsyth if(digest->len < dlen)
1217132f29a5Sforsyth error(exBadDigest);
121837da2899SCharles.Forsyth cdigest = digest->data;
121937da2899SCharles.Forsyth } else
122037da2899SCharles.Forsyth cdigest = nil;
122137da2899SCharles.Forsyth
122237da2899SCharles.Forsyth if(state == H){
122337da2899SCharles.Forsyth h = heap(TDigestState);
122437da2899SCharles.Forsyth ds = H2D(XDigestState*, h);
122537da2899SCharles.Forsyth memset(&ds->state, 0, sizeof(ds->state));
12269bca6be9Sforsyth } else
12279bca6be9Sforsyth ds = checktype(state, TDigestState, "DigestState", 1);
122837da2899SCharles.Forsyth
122937da2899SCharles.Forsyth (*fn)(cbuf, n, cdigest, &ds->state);
123037da2899SCharles.Forsyth
123137da2899SCharles.Forsyth return (Keyring_DigestState*)ds;
123237da2899SCharles.Forsyth }
123337da2899SCharles.Forsyth
123437da2899SCharles.Forsyth void
Keyring_sha1(void * fp)123537da2899SCharles.Forsyth Keyring_sha1(void *fp)
123637da2899SCharles.Forsyth {
123737da2899SCharles.Forsyth F_Keyring_sha1 *f;
123837da2899SCharles.Forsyth void *r;
123937da2899SCharles.Forsyth
124037da2899SCharles.Forsyth f = fp;
124137da2899SCharles.Forsyth r = *f->ret;
124237da2899SCharles.Forsyth *f->ret = H;
124337da2899SCharles.Forsyth destroy(r);
124437da2899SCharles.Forsyth
124537da2899SCharles.Forsyth *f->ret = keyring_digest_x(f->buf, f->n, f->digest, SHA1dlen, f->state, sha1);
124637da2899SCharles.Forsyth }
124737da2899SCharles.Forsyth
124837da2899SCharles.Forsyth void
Keyring_sha224(void * fp)1249f1dcfd03Sforsyth Keyring_sha224(void *fp)
1250f1dcfd03Sforsyth {
1251f1dcfd03Sforsyth F_Keyring_sha224 *f;
1252f1dcfd03Sforsyth void *r;
1253f1dcfd03Sforsyth
1254f1dcfd03Sforsyth f = fp;
1255f1dcfd03Sforsyth r = *f->ret;
1256f1dcfd03Sforsyth *f->ret = H;
1257f1dcfd03Sforsyth destroy(r);
1258f1dcfd03Sforsyth
1259f1dcfd03Sforsyth *f->ret = keyring_digest_x(f->buf, f->n, f->digest, SHA224dlen, f->state, sha224);
1260f1dcfd03Sforsyth }
1261f1dcfd03Sforsyth
1262f1dcfd03Sforsyth void
Keyring_sha256(void * fp)1263f1dcfd03Sforsyth Keyring_sha256(void *fp)
1264f1dcfd03Sforsyth {
1265f1dcfd03Sforsyth F_Keyring_sha256 *f;
1266f1dcfd03Sforsyth void *r;
1267f1dcfd03Sforsyth
1268f1dcfd03Sforsyth f = fp;
1269f1dcfd03Sforsyth r = *f->ret;
1270f1dcfd03Sforsyth *f->ret = H;
1271f1dcfd03Sforsyth destroy(r);
1272f1dcfd03Sforsyth
1273f1dcfd03Sforsyth *f->ret = keyring_digest_x(f->buf, f->n, f->digest, SHA256dlen, f->state, sha256);
1274f1dcfd03Sforsyth }
1275f1dcfd03Sforsyth
1276f1dcfd03Sforsyth void
Keyring_sha384(void * fp)1277f1dcfd03Sforsyth Keyring_sha384(void *fp)
1278f1dcfd03Sforsyth {
1279f1dcfd03Sforsyth F_Keyring_sha384 *f;
1280f1dcfd03Sforsyth void *r;
1281f1dcfd03Sforsyth
1282f1dcfd03Sforsyth f = fp;
1283f1dcfd03Sforsyth r = *f->ret;
1284f1dcfd03Sforsyth *f->ret = H;
1285f1dcfd03Sforsyth destroy(r);
1286f1dcfd03Sforsyth
1287f1dcfd03Sforsyth *f->ret = keyring_digest_x(f->buf, f->n, f->digest, SHA384dlen, f->state, sha384);
1288f1dcfd03Sforsyth }
1289f1dcfd03Sforsyth
1290f1dcfd03Sforsyth void
Keyring_sha512(void * fp)1291f1dcfd03Sforsyth Keyring_sha512(void *fp)
1292f1dcfd03Sforsyth {
1293f1dcfd03Sforsyth F_Keyring_sha512 *f;
1294f1dcfd03Sforsyth void *r;
1295f1dcfd03Sforsyth
1296f1dcfd03Sforsyth f = fp;
1297f1dcfd03Sforsyth r = *f->ret;
1298f1dcfd03Sforsyth *f->ret = H;
1299f1dcfd03Sforsyth destroy(r);
1300f1dcfd03Sforsyth
1301f1dcfd03Sforsyth *f->ret = keyring_digest_x(f->buf, f->n, f->digest, SHA512dlen, f->state, sha512);
1302f1dcfd03Sforsyth }
1303f1dcfd03Sforsyth
1304f1dcfd03Sforsyth void
Keyring_md5(void * fp)130537da2899SCharles.Forsyth Keyring_md5(void *fp)
130637da2899SCharles.Forsyth {
130737da2899SCharles.Forsyth F_Keyring_md5 *f;
130837da2899SCharles.Forsyth void *r;
130937da2899SCharles.Forsyth
131037da2899SCharles.Forsyth f = fp;
131137da2899SCharles.Forsyth r = *f->ret;
131237da2899SCharles.Forsyth *f->ret = H;
131337da2899SCharles.Forsyth destroy(r);
131437da2899SCharles.Forsyth
131537da2899SCharles.Forsyth *f->ret = keyring_digest_x(f->buf, f->n, f->digest, MD5dlen, f->state, md5);
131637da2899SCharles.Forsyth }
131737da2899SCharles.Forsyth
131837da2899SCharles.Forsyth void
Keyring_md4(void * fp)131937da2899SCharles.Forsyth Keyring_md4(void *fp)
132037da2899SCharles.Forsyth {
132137da2899SCharles.Forsyth F_Keyring_md4 *f;
132237da2899SCharles.Forsyth void *r;
132337da2899SCharles.Forsyth
132437da2899SCharles.Forsyth f = fp;
132537da2899SCharles.Forsyth r = *f->ret;
132637da2899SCharles.Forsyth *f->ret = H;
132737da2899SCharles.Forsyth destroy(r);
132837da2899SCharles.Forsyth
132937da2899SCharles.Forsyth *f->ret = keyring_digest_x(f->buf, f->n, f->digest, MD4dlen, f->state, md4);
133037da2899SCharles.Forsyth }
133137da2899SCharles.Forsyth
133237da2899SCharles.Forsyth static Keyring_DigestState*
keyring_hmac_x(Array * data,int n,Array * key,Array * digest,int dlen,Keyring_DigestState * state,DigestState * (* fn)(uchar *,ulong,uchar *,ulong,uchar *,DigestState *))133337da2899SCharles.Forsyth keyring_hmac_x(Array *data, int n, Array *key, Array *digest, int dlen, Keyring_DigestState *state, DigestState* (*fn)(uchar*, ulong, uchar*, ulong, uchar*, DigestState*))
133437da2899SCharles.Forsyth {
133537da2899SCharles.Forsyth Heap *h;
133637da2899SCharles.Forsyth XDigestState *ds;
133737da2899SCharles.Forsyth uchar *cdata, *cdigest;
133837da2899SCharles.Forsyth
133937da2899SCharles.Forsyth if(data != H){
134037da2899SCharles.Forsyth if(n > data->len)
134137da2899SCharles.Forsyth n = data->len;
134237da2899SCharles.Forsyth cdata = data->data;
134337da2899SCharles.Forsyth }else{
134437da2899SCharles.Forsyth if(n != 0)
1345132f29a5Sforsyth error(exInval);
134637da2899SCharles.Forsyth cdata = nil;
134737da2899SCharles.Forsyth }
134837da2899SCharles.Forsyth
134937da2899SCharles.Forsyth if(key == H || key->len > 64)
1350132f29a5Sforsyth error(exBadKey);
135137da2899SCharles.Forsyth
135237da2899SCharles.Forsyth if(digest != H){
135337da2899SCharles.Forsyth if(digest->len < dlen)
1354132f29a5Sforsyth error(exBadDigest);
135537da2899SCharles.Forsyth cdigest = digest->data;
135637da2899SCharles.Forsyth } else
135737da2899SCharles.Forsyth cdigest = nil;
135837da2899SCharles.Forsyth
135937da2899SCharles.Forsyth if(state == H){
136037da2899SCharles.Forsyth h = heap(TDigestState);
136137da2899SCharles.Forsyth ds = H2D(XDigestState*, h);
136237da2899SCharles.Forsyth memset(&ds->state, 0, sizeof(ds->state));
13639bca6be9Sforsyth } else
13649bca6be9Sforsyth ds = checktype(state, TDigestState, "DigestState", 1);
136537da2899SCharles.Forsyth
136637da2899SCharles.Forsyth (*fn)(cdata, n, key->data, key->len, cdigest, &ds->state);
136737da2899SCharles.Forsyth
136837da2899SCharles.Forsyth return (Keyring_DigestState*)ds;
136937da2899SCharles.Forsyth }
137037da2899SCharles.Forsyth
137137da2899SCharles.Forsyth void
Keyring_hmac_sha1(void * fp)137237da2899SCharles.Forsyth Keyring_hmac_sha1(void *fp)
137337da2899SCharles.Forsyth {
137437da2899SCharles.Forsyth F_Keyring_hmac_sha1 *f;
137537da2899SCharles.Forsyth void *r;
137637da2899SCharles.Forsyth
137737da2899SCharles.Forsyth f = fp;
137837da2899SCharles.Forsyth r = *f->ret;
137937da2899SCharles.Forsyth *f->ret = H;
138037da2899SCharles.Forsyth destroy(r);
138137da2899SCharles.Forsyth *f->ret = keyring_hmac_x(f->data, f->n, f->key, f->digest, SHA1dlen, f->state, hmac_sha1);
138237da2899SCharles.Forsyth }
138337da2899SCharles.Forsyth
138437da2899SCharles.Forsyth void
Keyring_hmac_md5(void * fp)138537da2899SCharles.Forsyth Keyring_hmac_md5(void *fp)
138637da2899SCharles.Forsyth {
138737da2899SCharles.Forsyth F_Keyring_hmac_md5 *f;
138837da2899SCharles.Forsyth void *r;
138937da2899SCharles.Forsyth
139037da2899SCharles.Forsyth f = fp;
139137da2899SCharles.Forsyth r = *f->ret;
139237da2899SCharles.Forsyth *f->ret = H;
139337da2899SCharles.Forsyth destroy(r);
139437da2899SCharles.Forsyth *f->ret = keyring_hmac_x(f->data, f->n, f->key, f->digest, MD5dlen, f->state, hmac_md5);
139537da2899SCharles.Forsyth }
139637da2899SCharles.Forsyth
139737da2899SCharles.Forsyth void
Keyring_dhparams(void * fp)139837da2899SCharles.Forsyth Keyring_dhparams(void *fp)
139937da2899SCharles.Forsyth {
140037da2899SCharles.Forsyth F_Keyring_dhparams *f;
140131a18a69SCharles.Forsyth mpint *p, *alpha;
140231a18a69SCharles.Forsyth void *v;
140337da2899SCharles.Forsyth
140437da2899SCharles.Forsyth f = fp;
140531a18a69SCharles.Forsyth v = f->ret->t0;
140637da2899SCharles.Forsyth f->ret->t0 = H;
140731a18a69SCharles.Forsyth destroy(v);
140831a18a69SCharles.Forsyth v = f->ret->t1;
140937da2899SCharles.Forsyth f->ret->t1 = H;
141031a18a69SCharles.Forsyth destroy(v);
141137da2899SCharles.Forsyth
141231a18a69SCharles.Forsyth p = mpnew(0);
141331a18a69SCharles.Forsyth alpha = mpnew(0);
141437da2899SCharles.Forsyth release();
141531a18a69SCharles.Forsyth if(f->nbits == 1024)
141631a18a69SCharles.Forsyth DSAprimes(alpha, p, nil);
141731a18a69SCharles.Forsyth else
141831a18a69SCharles.Forsyth gensafeprime(p, alpha, f->nbits, 0);
141937da2899SCharles.Forsyth acquire();
142037da2899SCharles.Forsyth f->ret->t0 = newIPint(alpha);
142137da2899SCharles.Forsyth f->ret->t1 = newIPint(p);
142237da2899SCharles.Forsyth }
142337da2899SCharles.Forsyth
142437da2899SCharles.Forsyth static int
sendmsg(int fd,void * buf,int n)142537da2899SCharles.Forsyth sendmsg(int fd, void *buf, int n)
142637da2899SCharles.Forsyth {
142737da2899SCharles.Forsyth char num[10];
142837da2899SCharles.Forsyth
142937da2899SCharles.Forsyth release();
143037da2899SCharles.Forsyth snprint(num, sizeof(num), "%4.4d\n", n);
143137da2899SCharles.Forsyth if(kwrite(fd, num, 5) != 5){
143237da2899SCharles.Forsyth acquire();
143337da2899SCharles.Forsyth return -1;
143437da2899SCharles.Forsyth }
143537da2899SCharles.Forsyth n = kwrite(fd, buf, n);
143637da2899SCharles.Forsyth acquire();
143737da2899SCharles.Forsyth return n;
143837da2899SCharles.Forsyth }
143937da2899SCharles.Forsyth
144037da2899SCharles.Forsyth void
Keyring_sendmsg(void * fp)144137da2899SCharles.Forsyth Keyring_sendmsg(void *fp)
144237da2899SCharles.Forsyth {
144337da2899SCharles.Forsyth F_Keyring_sendmsg *f;
144437da2899SCharles.Forsyth int n;
144537da2899SCharles.Forsyth
144637da2899SCharles.Forsyth f = fp;
144737da2899SCharles.Forsyth *f->ret = -1;
144837da2899SCharles.Forsyth if(f->fd == H || f->buf == H || f->n < 0)
144937da2899SCharles.Forsyth return;
145037da2899SCharles.Forsyth n = f->n;
14519bca6be9Sforsyth if(n < 0 || n > f->buf->len)
14529bca6be9Sforsyth error(exBounds);
145337da2899SCharles.Forsyth *f->ret = sendmsg(f->fd->fd, f->buf->data, n);
145437da2899SCharles.Forsyth }
145537da2899SCharles.Forsyth
145637da2899SCharles.Forsyth static int
senderr(int fd,char * err,int addrmt)145737da2899SCharles.Forsyth senderr(int fd, char *err, int addrmt)
145837da2899SCharles.Forsyth {
145937da2899SCharles.Forsyth char num[10];
146037da2899SCharles.Forsyth int n, m;
146137da2899SCharles.Forsyth
146237da2899SCharles.Forsyth release();
146337da2899SCharles.Forsyth n = strlen(err);
146437da2899SCharles.Forsyth m = 0;
146537da2899SCharles.Forsyth if(addrmt)
146637da2899SCharles.Forsyth m = strlen("remote: ");
146737da2899SCharles.Forsyth snprint(num, sizeof(num), "!%3.3d\n", n+m);
146837da2899SCharles.Forsyth if(kwrite(fd, num, 5) != 5){
146937da2899SCharles.Forsyth acquire();
147037da2899SCharles.Forsyth return -1;
147137da2899SCharles.Forsyth }
147237da2899SCharles.Forsyth if(addrmt)
147337da2899SCharles.Forsyth kwrite(fd, "remote: ", m);
147437da2899SCharles.Forsyth n = kwrite(fd, err, n);
147537da2899SCharles.Forsyth acquire();
147637da2899SCharles.Forsyth return n;
147737da2899SCharles.Forsyth }
147837da2899SCharles.Forsyth
147937da2899SCharles.Forsyth void
Keyring_senderrmsg(void * fp)148037da2899SCharles.Forsyth Keyring_senderrmsg(void *fp)
148137da2899SCharles.Forsyth {
148237da2899SCharles.Forsyth F_Keyring_senderrmsg *f;
148337da2899SCharles.Forsyth char *s;
148437da2899SCharles.Forsyth
148537da2899SCharles.Forsyth f = fp;
148637da2899SCharles.Forsyth *f->ret = -1;
148737da2899SCharles.Forsyth if(f->fd == H)
148837da2899SCharles.Forsyth return;
148937da2899SCharles.Forsyth s = string2c(f->s);
149037da2899SCharles.Forsyth if(senderr(f->fd->fd, s, 0) > 0)
149137da2899SCharles.Forsyth *f->ret = 0;
149237da2899SCharles.Forsyth }
149337da2899SCharles.Forsyth
149437da2899SCharles.Forsyth static int
nreadn(int fd,void * av,int n)149537da2899SCharles.Forsyth nreadn(int fd, void *av, int n)
149637da2899SCharles.Forsyth {
149737da2899SCharles.Forsyth
149837da2899SCharles.Forsyth char *a;
149937da2899SCharles.Forsyth long m, t;
150037da2899SCharles.Forsyth
150137da2899SCharles.Forsyth a = av;
150237da2899SCharles.Forsyth t = 0;
150337da2899SCharles.Forsyth while(t < n){
150437da2899SCharles.Forsyth m = kread(fd, a+t, n-t);
150537da2899SCharles.Forsyth if(m <= 0){
150637da2899SCharles.Forsyth if(t == 0)
150737da2899SCharles.Forsyth return m;
150837da2899SCharles.Forsyth break;
150937da2899SCharles.Forsyth }
151037da2899SCharles.Forsyth t += m;
151137da2899SCharles.Forsyth }
151237da2899SCharles.Forsyth return t;
151337da2899SCharles.Forsyth }
151437da2899SCharles.Forsyth
151537da2899SCharles.Forsyth #define MSG "input or format error"
151637da2899SCharles.Forsyth
151737da2899SCharles.Forsyth static void
getmsgerr(char * buf,int n,int r)151837da2899SCharles.Forsyth getmsgerr(char *buf, int n, int r)
151937da2899SCharles.Forsyth {
152037da2899SCharles.Forsyth char *e;
152137da2899SCharles.Forsyth int l;
152237da2899SCharles.Forsyth
152337da2899SCharles.Forsyth e = r>0? MSG: "hungup";
152437da2899SCharles.Forsyth l = strlen(e)+1;
152537da2899SCharles.Forsyth if(n > l)
152637da2899SCharles.Forsyth n = l;
152737da2899SCharles.Forsyth memmove(buf, e, n-1);
152837da2899SCharles.Forsyth buf[n-1] = 0;
152937da2899SCharles.Forsyth }
153037da2899SCharles.Forsyth
153137da2899SCharles.Forsyth static int
getmsg(int fd,char * buf,int n)153237da2899SCharles.Forsyth getmsg(int fd, char *buf, int n)
153337da2899SCharles.Forsyth {
153437da2899SCharles.Forsyth char num[6];
153537da2899SCharles.Forsyth int len, r;
153637da2899SCharles.Forsyth
153737da2899SCharles.Forsyth release();
153837da2899SCharles.Forsyth if((r = nreadn(fd, num, 5)) != 5){
153937da2899SCharles.Forsyth getmsgerr(buf, n, r);
154037da2899SCharles.Forsyth acquire();
154137da2899SCharles.Forsyth return -1;
154237da2899SCharles.Forsyth }
154337da2899SCharles.Forsyth num[5] = 0;
154437da2899SCharles.Forsyth
154537da2899SCharles.Forsyth if(num[0] == '!')
154637da2899SCharles.Forsyth len = strtoul(num+1, 0, 10);
154737da2899SCharles.Forsyth else
154837da2899SCharles.Forsyth len = strtoul(num, 0, 10);
154937da2899SCharles.Forsyth
155037da2899SCharles.Forsyth r = -1;
155137da2899SCharles.Forsyth if(len < 0 || len >= n || (r = nreadn(fd, buf, len)) != len){
155237da2899SCharles.Forsyth getmsgerr(buf, n, r);
155337da2899SCharles.Forsyth acquire();
155437da2899SCharles.Forsyth return -1;
155537da2899SCharles.Forsyth }
155637da2899SCharles.Forsyth
155737da2899SCharles.Forsyth buf[len] = 0;
155837da2899SCharles.Forsyth acquire();
155937da2899SCharles.Forsyth if(num[0] == '!')
156037da2899SCharles.Forsyth return -len;
156137da2899SCharles.Forsyth
156237da2899SCharles.Forsyth return len;
156337da2899SCharles.Forsyth }
156437da2899SCharles.Forsyth
156537da2899SCharles.Forsyth void
Keyring_getmsg(void * fp)156637da2899SCharles.Forsyth Keyring_getmsg(void *fp)
156737da2899SCharles.Forsyth {
156837da2899SCharles.Forsyth F_Keyring_getmsg *f;
156937da2899SCharles.Forsyth char *buf;
157037da2899SCharles.Forsyth int n;
15719bca6be9Sforsyth void *r;
157237da2899SCharles.Forsyth
157337da2899SCharles.Forsyth f = fp;
15749bca6be9Sforsyth r = *f->ret;
157537da2899SCharles.Forsyth *f->ret = H;
15769bca6be9Sforsyth destroy(r);
157737da2899SCharles.Forsyth if(f->fd == H){
157837da2899SCharles.Forsyth kwerrstr("nil fd");
157937da2899SCharles.Forsyth return;
158037da2899SCharles.Forsyth }
158137da2899SCharles.Forsyth
158237da2899SCharles.Forsyth buf = malloc(Maxmsg);
158337da2899SCharles.Forsyth if(buf == nil){
158437da2899SCharles.Forsyth kwerrstr(exNomem);
158537da2899SCharles.Forsyth return;
158637da2899SCharles.Forsyth }
158737da2899SCharles.Forsyth
158837da2899SCharles.Forsyth n = getmsg(f->fd->fd, buf, Maxmsg);
158937da2899SCharles.Forsyth if(n < 0){
159037da2899SCharles.Forsyth kwerrstr("%s", buf);
159137da2899SCharles.Forsyth free(buf);
159237da2899SCharles.Forsyth return;
159337da2899SCharles.Forsyth }
159437da2899SCharles.Forsyth
159537da2899SCharles.Forsyth *f->ret = mem2array(buf, n);
159637da2899SCharles.Forsyth free(buf);
159737da2899SCharles.Forsyth }
159837da2899SCharles.Forsyth
159937da2899SCharles.Forsyth void
Keyring_auth(void * fp)160037da2899SCharles.Forsyth Keyring_auth(void *fp)
160137da2899SCharles.Forsyth {
160237da2899SCharles.Forsyth F_Keyring_auth *f;
160331a18a69SCharles.Forsyth mpint *r0, *r1, *p, *alpha, *alphar0, *alphar1, *alphar0r1;
160437da2899SCharles.Forsyth SK *mysk;
160537da2899SCharles.Forsyth PK *mypk, *spk, *hispk;
160637da2899SCharles.Forsyth Certificate *cert, *hiscert, *alphacert;
160737da2899SCharles.Forsyth char *buf, *err;
160837da2899SCharles.Forsyth uchar *cvb;
160937da2899SCharles.Forsyth int n, fd, version;
161037da2899SCharles.Forsyth long now;
161137da2899SCharles.Forsyth
161237da2899SCharles.Forsyth hispk = H;
161337da2899SCharles.Forsyth hiscert = H;
161437da2899SCharles.Forsyth alphacert = H;
161537da2899SCharles.Forsyth err = nil;
161637da2899SCharles.Forsyth
161737da2899SCharles.Forsyth /* null out the return values */
161837da2899SCharles.Forsyth f = fp;
161937da2899SCharles.Forsyth destroy(f->ret->t0);
162037da2899SCharles.Forsyth f->ret->t0 = H;
162137da2899SCharles.Forsyth destroy(f->ret->t1);
162237da2899SCharles.Forsyth f->ret->t1 = H;
162331a18a69SCharles.Forsyth r0 = r1 = alphar0 = alphar1 = alphar0r1 = nil;
162437da2899SCharles.Forsyth
162537da2899SCharles.Forsyth /* check args */
162637da2899SCharles.Forsyth if(f->fd == H || f->fd->fd < 0){
162737da2899SCharles.Forsyth retstr("bad fd", &f->ret->t0);
162837da2899SCharles.Forsyth return;
162937da2899SCharles.Forsyth }
163037da2899SCharles.Forsyth fd = f->fd->fd;
163137da2899SCharles.Forsyth
163237da2899SCharles.Forsyth buf = malloc(Maxbuf);
163337da2899SCharles.Forsyth if(buf == nil){
163437da2899SCharles.Forsyth retstr(exNomem, &f->ret->t0);
163537da2899SCharles.Forsyth return;
163637da2899SCharles.Forsyth }
163737da2899SCharles.Forsyth
163837da2899SCharles.Forsyth /* send auth protocol version number */
163937da2899SCharles.Forsyth if(sendmsg(fd, "1", 1) <= 0){
164037da2899SCharles.Forsyth err = MSG;
164137da2899SCharles.Forsyth goto out;
164237da2899SCharles.Forsyth }
164337da2899SCharles.Forsyth
164437da2899SCharles.Forsyth /* get auth protocol version number */
164537da2899SCharles.Forsyth n = getmsg(fd, buf, Maxbuf-1);
164637da2899SCharles.Forsyth if(n < 0){
164737da2899SCharles.Forsyth err = buf;
164837da2899SCharles.Forsyth goto out;
164937da2899SCharles.Forsyth }
165037da2899SCharles.Forsyth buf[n] = 0;
165137da2899SCharles.Forsyth version = atoi(buf);
165237da2899SCharles.Forsyth if(version != 1 || n > 4){
165337da2899SCharles.Forsyth err = "incompatible authentication protocol";
165437da2899SCharles.Forsyth goto out;
165537da2899SCharles.Forsyth }
165637da2899SCharles.Forsyth
165737da2899SCharles.Forsyth if(f->info == H){
165837da2899SCharles.Forsyth err = "no authentication information";
165937da2899SCharles.Forsyth goto out;
166037da2899SCharles.Forsyth }
166137da2899SCharles.Forsyth if(f->info->p == H){
166237da2899SCharles.Forsyth err = "missing diffie hellman mod";
166337da2899SCharles.Forsyth goto out;
166437da2899SCharles.Forsyth }
166537da2899SCharles.Forsyth if(f->info->alpha == H){
166637da2899SCharles.Forsyth err = "missing diffie hellman base";
166737da2899SCharles.Forsyth goto out;
166837da2899SCharles.Forsyth }
166937da2899SCharles.Forsyth mysk = checkSK(f->info->mysk);
167037da2899SCharles.Forsyth if(mysk == H){
167137da2899SCharles.Forsyth err = "bad sk arg";
167237da2899SCharles.Forsyth goto out;
167337da2899SCharles.Forsyth }
167437da2899SCharles.Forsyth mypk = checkPK(f->info->mypk);
167537da2899SCharles.Forsyth if(mypk == H){
167637da2899SCharles.Forsyth err = "bad pk arg";
167737da2899SCharles.Forsyth goto out;
167837da2899SCharles.Forsyth }
167937da2899SCharles.Forsyth cert = checkCertificate(f->info->cert);
168037da2899SCharles.Forsyth if(cert == H){
168137da2899SCharles.Forsyth err = "bad certificate arg";
168237da2899SCharles.Forsyth goto out;
168337da2899SCharles.Forsyth }
168437da2899SCharles.Forsyth spk = checkPK(f->info->spk);
168537da2899SCharles.Forsyth if(spk == H){
168637da2899SCharles.Forsyth err = "bad signer key arg";
168737da2899SCharles.Forsyth goto out;
168837da2899SCharles.Forsyth }
168937da2899SCharles.Forsyth
169037da2899SCharles.Forsyth /* get alpha and p */
169131a18a69SCharles.Forsyth p = checkIPint(f->info->p);
169231a18a69SCharles.Forsyth alpha = checkIPint(f->info->alpha);
169337da2899SCharles.Forsyth
169437da2899SCharles.Forsyth if(p->sign == -1) {
169537da2899SCharles.Forsyth err = "-ve modulus";
169637da2899SCharles.Forsyth goto out;
169737da2899SCharles.Forsyth }
169837da2899SCharles.Forsyth
169937da2899SCharles.Forsyth r0 = mpnew(0);
170037da2899SCharles.Forsyth r1 = mpnew(0);
170137da2899SCharles.Forsyth alphar0 = mpnew(0);
170237da2899SCharles.Forsyth alphar0r1 = mpnew(0);
170337da2899SCharles.Forsyth
170437da2899SCharles.Forsyth /* generate alpha**r0 */
170537da2899SCharles.Forsyth if(0)print("X");
170637da2899SCharles.Forsyth release();
170731a18a69SCharles.Forsyth mprand(mpsignif(p), genrandom, r0);
170837da2899SCharles.Forsyth mpexp(alpha, r0, p, alphar0);
170937da2899SCharles.Forsyth acquire();
171037da2899SCharles.Forsyth if(0)print("Y");
171137da2899SCharles.Forsyth
171237da2899SCharles.Forsyth /* send alpha**r0 mod p, mycert, and mypk */
171337da2899SCharles.Forsyth n = bigtobase64(alphar0, buf, Maxbuf);
171437da2899SCharles.Forsyth if(sendmsg(fd, buf, n) <= 0){
171537da2899SCharles.Forsyth err = MSG;
171637da2899SCharles.Forsyth goto out;
171737da2899SCharles.Forsyth }
171837da2899SCharles.Forsyth
171937da2899SCharles.Forsyth n = certtostr(cert, buf, Maxbuf);
172037da2899SCharles.Forsyth if(sendmsg(fd, buf, n) <= 0){
172137da2899SCharles.Forsyth err = MSG;
172237da2899SCharles.Forsyth goto out;
172337da2899SCharles.Forsyth }
172437da2899SCharles.Forsyth
172537da2899SCharles.Forsyth n = pktostr(mypk, buf, Maxbuf);
172637da2899SCharles.Forsyth if(sendmsg(fd, buf, n) <= 0){
172737da2899SCharles.Forsyth err = MSG;
172837da2899SCharles.Forsyth goto out;
172937da2899SCharles.Forsyth }
173037da2899SCharles.Forsyth
173137da2899SCharles.Forsyth /* get alpha**r1 mod p, hiscert, hispk */
173237da2899SCharles.Forsyth n = getmsg(fd, buf, Maxbuf-1);
173337da2899SCharles.Forsyth if(n < 0){
173437da2899SCharles.Forsyth err = buf;
173537da2899SCharles.Forsyth goto out;
173637da2899SCharles.Forsyth }
173737da2899SCharles.Forsyth buf[n] = 0;
173837da2899SCharles.Forsyth alphar1 = strtomp(buf, nil, 64, nil);
173937da2899SCharles.Forsyth
174037da2899SCharles.Forsyth /* trying a fast one */
174137da2899SCharles.Forsyth if(mpcmp(p, alphar1) <= 0){
174237da2899SCharles.Forsyth err = "implausible parameter value";
174337da2899SCharles.Forsyth goto out;
174437da2899SCharles.Forsyth }
174537da2899SCharles.Forsyth
174637da2899SCharles.Forsyth /* if alpha**r1 == alpha**r0, someone may be trying a replay */
174737da2899SCharles.Forsyth if(mpcmp(alphar0, alphar1) == 0){
174837da2899SCharles.Forsyth err = "possible replay attack";
174937da2899SCharles.Forsyth goto out;
175037da2899SCharles.Forsyth }
175137da2899SCharles.Forsyth
175237da2899SCharles.Forsyth n = getmsg(fd, buf, Maxbuf-1);
175337da2899SCharles.Forsyth if(n < 0){
175437da2899SCharles.Forsyth err = buf;
175537da2899SCharles.Forsyth goto out;
175637da2899SCharles.Forsyth }
175737da2899SCharles.Forsyth buf[n] = 0;
175837da2899SCharles.Forsyth hiscert = strtocert(buf);
175937da2899SCharles.Forsyth if(hiscert == H){
1760bb045406SCharles.Forsyth err = "bad certificate syntax";
176137da2899SCharles.Forsyth goto out;
176237da2899SCharles.Forsyth }
176337da2899SCharles.Forsyth certimmutable(hiscert); /* hide from the garbage collector */
176437da2899SCharles.Forsyth
176537da2899SCharles.Forsyth n = getmsg(fd, buf, Maxbuf-1);
176637da2899SCharles.Forsyth if(n < 0){
176737da2899SCharles.Forsyth err = buf;
176837da2899SCharles.Forsyth goto out;
176937da2899SCharles.Forsyth }
177037da2899SCharles.Forsyth buf[n] = 0;
177137da2899SCharles.Forsyth hispk = strtopk(buf);
177237da2899SCharles.Forsyth if(hispk == H){
177337da2899SCharles.Forsyth err = "bad public key";
177437da2899SCharles.Forsyth goto out;
177537da2899SCharles.Forsyth }
177637da2899SCharles.Forsyth pkimmutable(hispk); /* hide from the garbage collector */
177737da2899SCharles.Forsyth
177837da2899SCharles.Forsyth /* verify his public key */
177937da2899SCharles.Forsyth if(verify(spk, hiscert, buf, n) == 0){
178037da2899SCharles.Forsyth err = "pk doesn't match certificate";
178137da2899SCharles.Forsyth goto out;
178237da2899SCharles.Forsyth }
178337da2899SCharles.Forsyth
178437da2899SCharles.Forsyth /* check expiration date - in seconds of epoch */
178537da2899SCharles.Forsyth
178637da2899SCharles.Forsyth now = osusectime()/1000000;
178737da2899SCharles.Forsyth if(hiscert->x.exp != 0 && hiscert->x.exp <= now){
178837da2899SCharles.Forsyth err = "certificate expired";
178937da2899SCharles.Forsyth goto out;
179037da2899SCharles.Forsyth }
179137da2899SCharles.Forsyth
179237da2899SCharles.Forsyth /* sign alpha**r0 and alpha**r1 and send */
179337da2899SCharles.Forsyth n = bigtobase64(alphar0, buf, Maxbuf);
179437da2899SCharles.Forsyth n += bigtobase64(alphar1, buf+n, Maxbuf-n);
179537da2899SCharles.Forsyth alphacert = sign(mysk, "sha1", 0, (uchar*)buf, n);
179637da2899SCharles.Forsyth n = certtostr(alphacert, buf, Maxbuf);
179737da2899SCharles.Forsyth if(sendmsg(fd, buf, n) <= 0){
179837da2899SCharles.Forsyth err = MSG;
179937da2899SCharles.Forsyth goto out;
180037da2899SCharles.Forsyth }
180137da2899SCharles.Forsyth certmutable(alphacert);
180237da2899SCharles.Forsyth destroy(alphacert);
180337da2899SCharles.Forsyth alphacert = H;
180437da2899SCharles.Forsyth
180537da2899SCharles.Forsyth /* get signature of alpha**r1 and alpha**r0 and verify */
180637da2899SCharles.Forsyth n = getmsg(fd, buf, Maxbuf-1);
180737da2899SCharles.Forsyth if(n < 0){
180837da2899SCharles.Forsyth err = buf;
180937da2899SCharles.Forsyth goto out;
181037da2899SCharles.Forsyth }
181137da2899SCharles.Forsyth buf[n] = 0;
181237da2899SCharles.Forsyth alphacert = strtocert(buf);
181337da2899SCharles.Forsyth if(alphacert == H){
181437da2899SCharles.Forsyth err = "alpha**r1 doesn't match certificate";
181537da2899SCharles.Forsyth goto out;
181637da2899SCharles.Forsyth }
181737da2899SCharles.Forsyth certimmutable(alphacert); /* hide from the garbage collector */
181837da2899SCharles.Forsyth n = bigtobase64(alphar1, buf, Maxbuf);
181937da2899SCharles.Forsyth n += bigtobase64(alphar0, buf+n, Maxbuf-n);
182037da2899SCharles.Forsyth if(verify(hispk, alphacert, buf, n) == 0){
182137da2899SCharles.Forsyth err = "bad certificate";
182237da2899SCharles.Forsyth goto out;
182337da2899SCharles.Forsyth }
182437da2899SCharles.Forsyth
182537da2899SCharles.Forsyth /* we are now authenticated and have a common secret, alpha**(r0*r1) */
182637da2899SCharles.Forsyth f->ret->t0 = stringdup(hispk->x.owner);
182737da2899SCharles.Forsyth mpexp(alphar1, r0, p, alphar0r1);
182837da2899SCharles.Forsyth n = mptobe(alphar0r1, nil, Maxbuf, &cvb);
182937da2899SCharles.Forsyth if(n < 0){
183037da2899SCharles.Forsyth err = "bad conversion";
183137da2899SCharles.Forsyth goto out;
183237da2899SCharles.Forsyth }
183337da2899SCharles.Forsyth f->ret->t1 = mem2array(cvb, n);
183437da2899SCharles.Forsyth free(cvb);
183537da2899SCharles.Forsyth
183637da2899SCharles.Forsyth out:
183737da2899SCharles.Forsyth /* return status */
183837da2899SCharles.Forsyth if(f->ret->t0 == H){
183937da2899SCharles.Forsyth if(err == buf)
184037da2899SCharles.Forsyth senderr(fd, "missing your authentication data", 1);
184137da2899SCharles.Forsyth else
184237da2899SCharles.Forsyth senderr(fd, err, 1);
184337da2899SCharles.Forsyth }else
184437da2899SCharles.Forsyth sendmsg(fd, "OK", 2);
184537da2899SCharles.Forsyth
184637da2899SCharles.Forsyth /* read responses */
184737da2899SCharles.Forsyth if(err != buf){
184837da2899SCharles.Forsyth for(;;){
184937da2899SCharles.Forsyth n = getmsg(fd, buf, Maxbuf-1);
185037da2899SCharles.Forsyth if(n < 0){
185137da2899SCharles.Forsyth destroy(f->ret->t0);
185237da2899SCharles.Forsyth f->ret->t0 = H;
185337da2899SCharles.Forsyth destroy(f->ret->t1);
185437da2899SCharles.Forsyth f->ret->t1 = H;
185537da2899SCharles.Forsyth if(err == nil){
185637da2899SCharles.Forsyth if(n < -1)
185737da2899SCharles.Forsyth err = buf;
185837da2899SCharles.Forsyth else
185937da2899SCharles.Forsyth err = MSG;
186037da2899SCharles.Forsyth }
186137da2899SCharles.Forsyth break;
186237da2899SCharles.Forsyth }
186337da2899SCharles.Forsyth if(n == 2 && buf[0] == 'O' && buf[1] == 'K')
186437da2899SCharles.Forsyth break;
186537da2899SCharles.Forsyth }
186637da2899SCharles.Forsyth }
186737da2899SCharles.Forsyth
186837da2899SCharles.Forsyth /* set error and id to nobody */
186937da2899SCharles.Forsyth if(f->ret->t0 == H){
187037da2899SCharles.Forsyth if(err == nil)
187137da2899SCharles.Forsyth err = MSG;
187237da2899SCharles.Forsyth retstr(err, &f->ret->t0);
187337da2899SCharles.Forsyth if(f->setid)
187437da2899SCharles.Forsyth setid("nobody", 1);
187537da2899SCharles.Forsyth } else {
187637da2899SCharles.Forsyth /* change user id */
187737da2899SCharles.Forsyth if(f->setid)
187837da2899SCharles.Forsyth setid(string2c(f->ret->t0), 1);
187937da2899SCharles.Forsyth }
188037da2899SCharles.Forsyth
188137da2899SCharles.Forsyth /* free resources */
188237da2899SCharles.Forsyth if(hispk != H){
188337da2899SCharles.Forsyth pkmutable(hispk);
188437da2899SCharles.Forsyth destroy(hispk);
188537da2899SCharles.Forsyth }
188637da2899SCharles.Forsyth if(hiscert != H){
188737da2899SCharles.Forsyth certmutable(hiscert);
188837da2899SCharles.Forsyth destroy(hiscert);
188937da2899SCharles.Forsyth }
189037da2899SCharles.Forsyth if(alphacert != H){
189137da2899SCharles.Forsyth certmutable(alphacert);
189237da2899SCharles.Forsyth destroy(alphacert);
189337da2899SCharles.Forsyth }
189437da2899SCharles.Forsyth free(buf);
189531a18a69SCharles.Forsyth if(r0 != nil){
189637da2899SCharles.Forsyth mpfree(r0);
189737da2899SCharles.Forsyth mpfree(r1);
189837da2899SCharles.Forsyth mpfree(alphar0);
189937da2899SCharles.Forsyth mpfree(alphar1);
190037da2899SCharles.Forsyth mpfree(alphar0r1);
190137da2899SCharles.Forsyth }
190237da2899SCharles.Forsyth }
190337da2899SCharles.Forsyth
190437da2899SCharles.Forsyth static Keyring_Authinfo*
newAuthinfo(void)190537da2899SCharles.Forsyth newAuthinfo(void)
190637da2899SCharles.Forsyth {
190737da2899SCharles.Forsyth return H2D(Keyring_Authinfo*, heap(TAuthinfo));
190837da2899SCharles.Forsyth }
190937da2899SCharles.Forsyth
191037da2899SCharles.Forsyth void
Keyring_writeauthinfo(void * fp)191137da2899SCharles.Forsyth Keyring_writeauthinfo(void *fp)
191237da2899SCharles.Forsyth {
191337da2899SCharles.Forsyth F_Keyring_writeauthinfo *f;
191437da2899SCharles.Forsyth int n, fd;
191537da2899SCharles.Forsyth char *buf;
191637da2899SCharles.Forsyth PK *spk;
191737da2899SCharles.Forsyth SK *mysk;
191837da2899SCharles.Forsyth Certificate *c;
1919*7de2b42dSforsyth mpint *p, *alpha;
192037da2899SCharles.Forsyth
192137da2899SCharles.Forsyth f = fp;
192237da2899SCharles.Forsyth *f->ret = -1;
192337da2899SCharles.Forsyth
192437da2899SCharles.Forsyth if(f->filename == H)
1925*7de2b42dSforsyth error(exNilref);
192637da2899SCharles.Forsyth if(f->info == H)
1927*7de2b42dSforsyth error(exNilref);
1928*7de2b42dSforsyth alpha = checkIPint(f->info->alpha);
1929*7de2b42dSforsyth p = checkIPint(f->info->p);
193037da2899SCharles.Forsyth spk = checkPK(f->info->spk);
193137da2899SCharles.Forsyth mysk = checkSK(f->info->mysk);
193237da2899SCharles.Forsyth c = checkCertificate(f->info->cert);
193337da2899SCharles.Forsyth
193437da2899SCharles.Forsyth buf = malloc(Maxbuf);
193537da2899SCharles.Forsyth if(buf == nil)
193637da2899SCharles.Forsyth return;
193737da2899SCharles.Forsyth
193837da2899SCharles.Forsyth /*
193937da2899SCharles.Forsyth * The file may already exist or be a file2chan file so first
194037da2899SCharles.Forsyth * try opening with truncation since create will change the
194137da2899SCharles.Forsyth * permissions of the file and create doesn't work with a
194237da2899SCharles.Forsyth * file2chan.
194337da2899SCharles.Forsyth */
194437da2899SCharles.Forsyth release();
194537da2899SCharles.Forsyth fd = kopen(string2c(f->filename), OTRUNC|OWRITE);
194637da2899SCharles.Forsyth if(fd < 0)
194737da2899SCharles.Forsyth fd = kcreate(string2c(f->filename), OWRITE, 0600);
194837da2899SCharles.Forsyth if(fd < 0)
194937da2899SCharles.Forsyth fd = kopen(string2c(f->filename), OWRITE);
195037da2899SCharles.Forsyth acquire();
195137da2899SCharles.Forsyth if(fd < 0)
195237da2899SCharles.Forsyth goto out;
195337da2899SCharles.Forsyth
195437da2899SCharles.Forsyth /* signer's public key */
195537da2899SCharles.Forsyth n = pktostr(spk, buf, Maxmsg);
195637da2899SCharles.Forsyth if(sendmsg(fd, buf, n) <= 0)
195737da2899SCharles.Forsyth goto out;
195837da2899SCharles.Forsyth
195937da2899SCharles.Forsyth /* certificate for my public key */
196037da2899SCharles.Forsyth n = certtostr(c, buf, Maxmsg);
196137da2899SCharles.Forsyth if(sendmsg(fd, buf, n) <= 0)
196237da2899SCharles.Forsyth goto out;
196337da2899SCharles.Forsyth
196437da2899SCharles.Forsyth /* my secret/public key */
196537da2899SCharles.Forsyth n = sktostr(mysk, buf, Maxmsg);
196637da2899SCharles.Forsyth if(sendmsg(fd, buf, n) <= 0)
196737da2899SCharles.Forsyth goto out;
196837da2899SCharles.Forsyth
196937da2899SCharles.Forsyth /* diffie hellman base */
1970*7de2b42dSforsyth n = bigtobase64(alpha, buf, Maxbuf);
197137da2899SCharles.Forsyth if(sendmsg(fd, buf, n) <= 0)
197237da2899SCharles.Forsyth goto out;
197337da2899SCharles.Forsyth
197437da2899SCharles.Forsyth /* diffie hellman modulus */
1975*7de2b42dSforsyth n = bigtobase64(p, buf, Maxbuf);
197637da2899SCharles.Forsyth if(sendmsg(fd, buf, n) <= 0)
197737da2899SCharles.Forsyth goto out;
197837da2899SCharles.Forsyth
197937da2899SCharles.Forsyth *f->ret = 0;
198037da2899SCharles.Forsyth out:
198137da2899SCharles.Forsyth free(buf);
198237da2899SCharles.Forsyth if(fd >= 0){
198337da2899SCharles.Forsyth release();
198437da2899SCharles.Forsyth kclose(fd);
198537da2899SCharles.Forsyth acquire();
198637da2899SCharles.Forsyth }
198737da2899SCharles.Forsyth }
198837da2899SCharles.Forsyth
198937da2899SCharles.Forsyth void
Keyring_readauthinfo(void * fp)199037da2899SCharles.Forsyth Keyring_readauthinfo(void *fp)
199137da2899SCharles.Forsyth {
199237da2899SCharles.Forsyth F_Keyring_readauthinfo *f;
199337da2899SCharles.Forsyth int fd;
199437da2899SCharles.Forsyth char *buf;
199537da2899SCharles.Forsyth int n, ok;
199637da2899SCharles.Forsyth PK *mypk;
199737da2899SCharles.Forsyth SK *mysk;
199837da2899SCharles.Forsyth SigAlg *sa;
199937da2899SCharles.Forsyth Keyring_Authinfo *ai;
200031a18a69SCharles.Forsyth mpint *b;
20019bca6be9Sforsyth void *r;
200237da2899SCharles.Forsyth
200337da2899SCharles.Forsyth f = fp;
20049bca6be9Sforsyth r = *f->ret;
200537da2899SCharles.Forsyth *f->ret = H;
20069bca6be9Sforsyth destroy(r);
200737da2899SCharles.Forsyth
200837da2899SCharles.Forsyth ok = 0;
200937da2899SCharles.Forsyth
201037da2899SCharles.Forsyth if(f->filename == H)
201137da2899SCharles.Forsyth return;
201237da2899SCharles.Forsyth
201337da2899SCharles.Forsyth buf = malloc(Maxbuf);
201437da2899SCharles.Forsyth if(buf == nil)
201537da2899SCharles.Forsyth return;
201637da2899SCharles.Forsyth
201737da2899SCharles.Forsyth ai = newAuthinfo();
201837da2899SCharles.Forsyth *f->ret = ai;
201937da2899SCharles.Forsyth
202037da2899SCharles.Forsyth release();
202137da2899SCharles.Forsyth fd = kopen(string2c(f->filename), OREAD);
202237da2899SCharles.Forsyth acquire();
202337da2899SCharles.Forsyth if(fd < 0)
202437da2899SCharles.Forsyth goto out;
202537da2899SCharles.Forsyth
202637da2899SCharles.Forsyth /* signer's public key */
202737da2899SCharles.Forsyth n = getmsg(fd, buf, Maxmsg);
202837da2899SCharles.Forsyth if(n < 0)
202937da2899SCharles.Forsyth goto out;
203037da2899SCharles.Forsyth
203137da2899SCharles.Forsyth ai->spk = (Keyring_PK*)strtopk(buf);
203237da2899SCharles.Forsyth if(ai->spk == H)
203337da2899SCharles.Forsyth goto out;
203437da2899SCharles.Forsyth
203537da2899SCharles.Forsyth /* certificate for my public key */
203637da2899SCharles.Forsyth n = getmsg(fd, buf, Maxmsg);
203737da2899SCharles.Forsyth if(n < 0)
203837da2899SCharles.Forsyth goto out;
203937da2899SCharles.Forsyth ai->cert = (Keyring_Certificate*)strtocert(buf);
204037da2899SCharles.Forsyth if(ai->cert == H)
204137da2899SCharles.Forsyth goto out;
204237da2899SCharles.Forsyth
204337da2899SCharles.Forsyth /* my secret/public key */
204437da2899SCharles.Forsyth n = getmsg(fd, buf, Maxmsg);
204537da2899SCharles.Forsyth if(n < 0)
204637da2899SCharles.Forsyth goto out;
204737da2899SCharles.Forsyth mysk = strtosk(buf);
204837da2899SCharles.Forsyth ai->mysk = (Keyring_SK*)mysk;
204937da2899SCharles.Forsyth if(mysk == H)
205037da2899SCharles.Forsyth goto out;
205137da2899SCharles.Forsyth sa = checkSigAlg(mysk->x.sa);
205237da2899SCharles.Forsyth mypk = newPK(sa, stringdup(mysk->x.owner), 1);
205337da2899SCharles.Forsyth mypk->key = (*sa->vec->sk2pk)(mysk->key);
205437da2899SCharles.Forsyth ai->mypk = (Keyring_PK*)mypk;
205537da2899SCharles.Forsyth
205637da2899SCharles.Forsyth /* diffie hellman base */
205737da2899SCharles.Forsyth n = getmsg(fd, buf, Maxmsg);
205837da2899SCharles.Forsyth if(n < 0)
205937da2899SCharles.Forsyth goto out;
206037da2899SCharles.Forsyth b = strtomp(buf, nil, 64, nil);
206137da2899SCharles.Forsyth ai->alpha = newIPint(b);
206237da2899SCharles.Forsyth
206337da2899SCharles.Forsyth /* diffie hellman modulus */
206437da2899SCharles.Forsyth n = getmsg(fd, buf, Maxmsg);
206537da2899SCharles.Forsyth if(n < 0)
206637da2899SCharles.Forsyth goto out;
206737da2899SCharles.Forsyth b = strtomp(buf, nil, 64, nil);
206837da2899SCharles.Forsyth ai->p = newIPint(b);
206937da2899SCharles.Forsyth ok = 1;
207037da2899SCharles.Forsyth out:
207137da2899SCharles.Forsyth if(!ok){
20729bca6be9Sforsyth r = *f->ret;
207337da2899SCharles.Forsyth *f->ret = H;
20749bca6be9Sforsyth destroy(r);
207537da2899SCharles.Forsyth }
207637da2899SCharles.Forsyth free(buf);
207737da2899SCharles.Forsyth if(fd >= 0){
207837da2899SCharles.Forsyth release();
207937da2899SCharles.Forsyth kclose(fd);
208037da2899SCharles.Forsyth acquire();
208137da2899SCharles.Forsyth kwerrstr("%q: %s", string2c(f->filename), MSG);
208237da2899SCharles.Forsyth }
208337da2899SCharles.Forsyth }
208437da2899SCharles.Forsyth
208537da2899SCharles.Forsyth void
keyringmodinit(void)208637da2899SCharles.Forsyth keyringmodinit(void)
208737da2899SCharles.Forsyth {
208837da2899SCharles.Forsyth SigAlgVec *sav;
208937da2899SCharles.Forsyth extern SigAlgVec* elgamalinit(void);
209037da2899SCharles.Forsyth extern SigAlgVec* rsainit(void);
209137da2899SCharles.Forsyth extern SigAlgVec* dsainit(void);
209237da2899SCharles.Forsyth
2093*7de2b42dSforsyth ipintsmodinit(); /* in case only Keyring is configured */
209437da2899SCharles.Forsyth TSigAlg = dtype(freeSigAlg, sizeof(SigAlg), SigAlgmap, sizeof(SigAlgmap));
209537da2899SCharles.Forsyth TSK = dtype(freeSK, sizeof(SK), SKmap, sizeof(SKmap));
209637da2899SCharles.Forsyth TPK = dtype(freePK, sizeof(PK), PKmap, sizeof(PKmap));
209737da2899SCharles.Forsyth TCertificate = dtype(freeCertificate, sizeof(Certificate), Certificatemap,
209837da2899SCharles.Forsyth sizeof(Certificatemap));
209937da2899SCharles.Forsyth TDigestState = dtype(freeheap, sizeof(XDigestState), DigestStatemap,
210037da2899SCharles.Forsyth sizeof(DigestStatemap));
210137da2899SCharles.Forsyth TAESstate = dtype(freeheap, sizeof(XAESstate), AESstatemap,
210237da2899SCharles.Forsyth sizeof(AESstatemap));
210337da2899SCharles.Forsyth TDESstate = dtype(freeheap, sizeof(XDESstate), DESstatemap,
210437da2899SCharles.Forsyth sizeof(DESstatemap));
210537da2899SCharles.Forsyth TIDEAstate = dtype(freeheap, sizeof(XIDEAstate), IDEAstatemap,
210637da2899SCharles.Forsyth sizeof(IDEAstatemap));
2107ca1042d3SCharles.Forsyth TBFstate = dtype(freeheap, sizeof(XBFstate), BFstatemap,
2108ca1042d3SCharles.Forsyth sizeof(BFstatemap));
210937da2899SCharles.Forsyth TRC4state = dtype(freeheap, sizeof(XRC4state), RC4statemap,
211037da2899SCharles.Forsyth sizeof(RC4statemap));
211137da2899SCharles.Forsyth TAuthinfo = dtype(freeheap, sizeof(Keyring_Authinfo), Authinfomap, sizeof(Authinfomap));
2112ca1042d3SCharles.Forsyth TDSAsk = dtype(freeheap, sizeof(Keyring_DSAsk), DSAskmap, sizeof(DSAskmap));
2113ca1042d3SCharles.Forsyth TDSApk = dtype(freeheap, sizeof(Keyring_DSApk), DSApkmap, sizeof(DSApkmap));
2114ca1042d3SCharles.Forsyth TDSAsig = dtype(freeheap, sizeof(Keyring_DSAsig), DSAsigmap, sizeof(DSAsigmap));
2115ca1042d3SCharles.Forsyth TEGsk = dtype(freeheap, sizeof(Keyring_EGsk), EGskmap, sizeof(EGskmap));
2116ca1042d3SCharles.Forsyth TEGpk = dtype(freeheap, sizeof(Keyring_EGpk), EGpkmap, sizeof(EGpkmap));
2117ca1042d3SCharles.Forsyth TEGsig = dtype(freeheap, sizeof(Keyring_EGsig), EGsigmap, sizeof(EGsigmap));
2118ca1042d3SCharles.Forsyth TRSAsk = dtype(freeheap, sizeof(Keyring_RSAsk), RSAskmap, sizeof(RSAskmap));
2119ca1042d3SCharles.Forsyth TRSApk = dtype(freeheap, sizeof(Keyring_RSApk), RSApkmap, sizeof(RSApkmap));
2120ca1042d3SCharles.Forsyth TRSAsig = dtype(freeheap, sizeof(Keyring_RSAsig), RSAsigmap, sizeof(RSAsigmap));
212137da2899SCharles.Forsyth
212237da2899SCharles.Forsyth if((sav = elgamalinit()) != nil)
212337da2899SCharles.Forsyth algs[nalg++] = sav;
212437da2899SCharles.Forsyth if((sav = rsainit()) != nil)
212537da2899SCharles.Forsyth algs[nalg++] = sav;
212637da2899SCharles.Forsyth if((sav = dsainit()) != nil)
212737da2899SCharles.Forsyth algs[nalg++] = sav;
212837da2899SCharles.Forsyth
212937da2899SCharles.Forsyth fmtinstall('U', big64conv);
213037da2899SCharles.Forsyth builtinmod("$Keyring", Keyringmodtab, Keyringmodlen);
213137da2899SCharles.Forsyth }
213237da2899SCharles.Forsyth
213337da2899SCharles.Forsyth /*
213437da2899SCharles.Forsyth * IO on a delimited channel. A message starting with 0x00 is a normal
213537da2899SCharles.Forsyth * message. One starting with 0xff is an error string.
213637da2899SCharles.Forsyth *
213737da2899SCharles.Forsyth * return negative number for error messages (including hangup)
213837da2899SCharles.Forsyth */
213937da2899SCharles.Forsyth static int
getbuf(int fd,uchar * buf,int n,char * err,int nerr)214037da2899SCharles.Forsyth getbuf(int fd, uchar *buf, int n, char *err, int nerr)
214137da2899SCharles.Forsyth {
214237da2899SCharles.Forsyth int len;
214337da2899SCharles.Forsyth
214437da2899SCharles.Forsyth release();
214537da2899SCharles.Forsyth len = kread(fd, buf, n);
214637da2899SCharles.Forsyth acquire();
214737da2899SCharles.Forsyth if(len <= 0){
214837da2899SCharles.Forsyth strncpy(err, "hungup", nerr);
214937da2899SCharles.Forsyth buf[nerr-1] = 0;
215037da2899SCharles.Forsyth return -1;
215137da2899SCharles.Forsyth }
215237da2899SCharles.Forsyth if(buf[0] == 0)
215337da2899SCharles.Forsyth return len-1;
215437da2899SCharles.Forsyth if(buf[0] != 0xff){
215537da2899SCharles.Forsyth /*
215637da2899SCharles.Forsyth * this happens when the client's password is wrong: both sides use a digest of the
215737da2899SCharles.Forsyth * password as a crypt key for devssl. When they don't match decryption garbles
215837da2899SCharles.Forsyth * messages
215937da2899SCharles.Forsyth */
216037da2899SCharles.Forsyth strncpy(err, "failure", nerr);
216137da2899SCharles.Forsyth err[nerr-1] = 0;
216237da2899SCharles.Forsyth return -1;
216337da2899SCharles.Forsyth }
216437da2899SCharles.Forsyth
216537da2899SCharles.Forsyth /* error string */
216637da2899SCharles.Forsyth len--;
216737da2899SCharles.Forsyth if(len < 1){
216837da2899SCharles.Forsyth strncpy(err, "unknown", nerr);
216937da2899SCharles.Forsyth err[nerr-1] = 0;
217037da2899SCharles.Forsyth } else {
217137da2899SCharles.Forsyth if(len >= nerr)
217237da2899SCharles.Forsyth len = nerr-1;
217337da2899SCharles.Forsyth memmove(err, buf+1, len);
217437da2899SCharles.Forsyth err[len] = 0;
217537da2899SCharles.Forsyth }
217637da2899SCharles.Forsyth return -1;
217737da2899SCharles.Forsyth }
217837da2899SCharles.Forsyth
217937da2899SCharles.Forsyth void
Keyring_getstring(void * fp)218037da2899SCharles.Forsyth Keyring_getstring(void *fp)
218137da2899SCharles.Forsyth {
218237da2899SCharles.Forsyth F_Keyring_getstring *f;
218337da2899SCharles.Forsyth uchar *buf;
218437da2899SCharles.Forsyth char err[64];
218537da2899SCharles.Forsyth int n;
218637da2899SCharles.Forsyth
218737da2899SCharles.Forsyth f = fp;
218837da2899SCharles.Forsyth destroy(f->ret->t0);
218937da2899SCharles.Forsyth f->ret->t0 = H;
219037da2899SCharles.Forsyth destroy(f->ret->t1);
219137da2899SCharles.Forsyth f->ret->t1 = H;
219237da2899SCharles.Forsyth
219337da2899SCharles.Forsyth if(f->fd == H)
219437da2899SCharles.Forsyth return;
219537da2899SCharles.Forsyth
219637da2899SCharles.Forsyth buf = malloc(Maxmsg);
219737da2899SCharles.Forsyth if(buf == nil)
219837da2899SCharles.Forsyth return;
219937da2899SCharles.Forsyth
220037da2899SCharles.Forsyth n = getbuf(f->fd->fd, buf, Maxmsg, err, sizeof(err));
220137da2899SCharles.Forsyth if(n < 0)
220237da2899SCharles.Forsyth retnstr(err, strlen(err), &f->ret->t1);
220337da2899SCharles.Forsyth else
220437da2899SCharles.Forsyth retnstr(((char*)buf)+1, n, &f->ret->t0);
220537da2899SCharles.Forsyth
220637da2899SCharles.Forsyth free(buf);
220737da2899SCharles.Forsyth }
220837da2899SCharles.Forsyth
220937da2899SCharles.Forsyth void
Keyring_getbytearray(void * fp)221037da2899SCharles.Forsyth Keyring_getbytearray(void *fp)
221137da2899SCharles.Forsyth {
221237da2899SCharles.Forsyth F_Keyring_getbytearray *f;
221337da2899SCharles.Forsyth uchar *buf;
221437da2899SCharles.Forsyth char err[64];
221537da2899SCharles.Forsyth int n;
221637da2899SCharles.Forsyth
221737da2899SCharles.Forsyth f = fp;
221837da2899SCharles.Forsyth destroy(f->ret->t0);
221937da2899SCharles.Forsyth f->ret->t0 = H;
222037da2899SCharles.Forsyth destroy(f->ret->t1);
222137da2899SCharles.Forsyth f->ret->t1 = H;
222237da2899SCharles.Forsyth
222337da2899SCharles.Forsyth if(f->fd == H)
222437da2899SCharles.Forsyth return;
222537da2899SCharles.Forsyth
222637da2899SCharles.Forsyth buf = malloc(Maxmsg);
222737da2899SCharles.Forsyth if(buf == nil)
222837da2899SCharles.Forsyth return;
222937da2899SCharles.Forsyth
223037da2899SCharles.Forsyth n = getbuf(f->fd->fd, buf, Maxmsg, err, sizeof(err));
223137da2899SCharles.Forsyth if(n < 0)
223237da2899SCharles.Forsyth retnstr(err, strlen(err), &f->ret->t1);
223337da2899SCharles.Forsyth else
223437da2899SCharles.Forsyth f->ret->t0 = mem2array(buf+1, n);
223537da2899SCharles.Forsyth
223637da2899SCharles.Forsyth free(buf);
223737da2899SCharles.Forsyth }
223837da2899SCharles.Forsyth
223937da2899SCharles.Forsyth static int
putbuf(int fd,void * p,int n)224037da2899SCharles.Forsyth putbuf(int fd, void *p, int n)
224137da2899SCharles.Forsyth {
224237da2899SCharles.Forsyth char *buf;
224337da2899SCharles.Forsyth
224437da2899SCharles.Forsyth buf = malloc(Maxmsg);
224537da2899SCharles.Forsyth if(buf == nil)
224637da2899SCharles.Forsyth return -1;
224737da2899SCharles.Forsyth
224837da2899SCharles.Forsyth release();
224937da2899SCharles.Forsyth buf[0] = 0;
225037da2899SCharles.Forsyth if(n < 0){
225137da2899SCharles.Forsyth buf[0] = 0xff;
225237da2899SCharles.Forsyth n = -n;
225337da2899SCharles.Forsyth }
225437da2899SCharles.Forsyth if(n >= Maxmsg)
225537da2899SCharles.Forsyth n = Maxmsg - 1;
225637da2899SCharles.Forsyth memmove(buf+1, p, n);
225737da2899SCharles.Forsyth n = kwrite(fd, buf, n+1);
225837da2899SCharles.Forsyth acquire();
225937da2899SCharles.Forsyth
226037da2899SCharles.Forsyth free(buf);
226137da2899SCharles.Forsyth return n;
226237da2899SCharles.Forsyth }
226337da2899SCharles.Forsyth
226437da2899SCharles.Forsyth void
Keyring_putstring(void * fp)226537da2899SCharles.Forsyth Keyring_putstring(void *fp)
226637da2899SCharles.Forsyth {
226737da2899SCharles.Forsyth F_Keyring_putstring *f;
226837da2899SCharles.Forsyth
226937da2899SCharles.Forsyth f = fp;
227037da2899SCharles.Forsyth *f->ret = -1;
227137da2899SCharles.Forsyth if(f->fd == H || f->s == H)
227237da2899SCharles.Forsyth return;
227337da2899SCharles.Forsyth *f->ret = putbuf(f->fd->fd, string2c(f->s), strlen(string2c(f->s)));
227437da2899SCharles.Forsyth }
227537da2899SCharles.Forsyth
227637da2899SCharles.Forsyth void
Keyring_puterror(void * fp)227737da2899SCharles.Forsyth Keyring_puterror(void *fp)
227837da2899SCharles.Forsyth {
227937da2899SCharles.Forsyth F_Keyring_puterror *f;
228037da2899SCharles.Forsyth
228137da2899SCharles.Forsyth f = fp;
228237da2899SCharles.Forsyth *f->ret = -1;
228337da2899SCharles.Forsyth if(f->fd == H || f->s == H)
228437da2899SCharles.Forsyth return;
228537da2899SCharles.Forsyth *f->ret = putbuf(f->fd->fd, string2c(f->s), -strlen(string2c(f->s)));
228637da2899SCharles.Forsyth }
228737da2899SCharles.Forsyth
228837da2899SCharles.Forsyth void
Keyring_putbytearray(void * fp)228937da2899SCharles.Forsyth Keyring_putbytearray(void *fp)
229037da2899SCharles.Forsyth {
229137da2899SCharles.Forsyth F_Keyring_putbytearray *f;
229237da2899SCharles.Forsyth int n;
229337da2899SCharles.Forsyth
229437da2899SCharles.Forsyth f = fp;
229537da2899SCharles.Forsyth *f->ret = -1;
229637da2899SCharles.Forsyth if(f->fd == H || f->a == H)
229737da2899SCharles.Forsyth return;
229837da2899SCharles.Forsyth n = f->n;
22999bca6be9Sforsyth if(n < 0 || n > f->a->len)
23009bca6be9Sforsyth error(exBounds);
230137da2899SCharles.Forsyth *f->ret = putbuf(f->fd->fd, f->a->data, n);
230237da2899SCharles.Forsyth }
230337da2899SCharles.Forsyth
230437da2899SCharles.Forsyth void
Keyring_dessetup(void * fp)230537da2899SCharles.Forsyth Keyring_dessetup(void *fp)
230637da2899SCharles.Forsyth {
230737da2899SCharles.Forsyth F_Keyring_dessetup *f;
230837da2899SCharles.Forsyth Heap *h;
230937da2899SCharles.Forsyth XDESstate *ds;
231037da2899SCharles.Forsyth uchar *ivec;
23119bca6be9Sforsyth void *r;
231237da2899SCharles.Forsyth
231337da2899SCharles.Forsyth f = fp;
23149bca6be9Sforsyth r = *f->ret;
231537da2899SCharles.Forsyth *f->ret = H;
23169bca6be9Sforsyth destroy(r);
231737da2899SCharles.Forsyth
2318132f29a5Sforsyth if(f->key == H || f->key->len < 8)
2319132f29a5Sforsyth error(exBadKey);
2320132f29a5Sforsyth if(f->ivec != H){
2321132f29a5Sforsyth if(f->ivec->len < 8)
2322132f29a5Sforsyth error(exBadIvec);
232337da2899SCharles.Forsyth ivec = f->ivec->data;
2324132f29a5Sforsyth }else
2325132f29a5Sforsyth ivec = nil;
232637da2899SCharles.Forsyth
232737da2899SCharles.Forsyth h = heap(TDESstate);
232837da2899SCharles.Forsyth ds = H2D(XDESstate*, h);
232937da2899SCharles.Forsyth setupDESstate(&ds->state, f->key->data, ivec);
233037da2899SCharles.Forsyth
233137da2899SCharles.Forsyth *f->ret = (Keyring_DESstate*)ds;
233237da2899SCharles.Forsyth }
233337da2899SCharles.Forsyth
233437da2899SCharles.Forsyth void
Keyring_desecb(void * fp)233537da2899SCharles.Forsyth Keyring_desecb(void *fp)
233637da2899SCharles.Forsyth {
233737da2899SCharles.Forsyth F_Keyring_desecb *f;
233837da2899SCharles.Forsyth XDESstate *ds;
233937da2899SCharles.Forsyth int i;
234037da2899SCharles.Forsyth uchar *p;
234137da2899SCharles.Forsyth
234237da2899SCharles.Forsyth f = fp;
234337da2899SCharles.Forsyth
2344ca1042d3SCharles.Forsyth if(f->buf == H)
234537da2899SCharles.Forsyth return;
23469bca6be9Sforsyth if(f->n < 0 || f->n > f->buf->len)
23479bca6be9Sforsyth error(exBounds);
234837da2899SCharles.Forsyth if(f->n & 7)
2349132f29a5Sforsyth error(exBadBsize);
235037da2899SCharles.Forsyth
23519bca6be9Sforsyth ds = checktype(f->state, TDESstate, exBadState, 0);
235237da2899SCharles.Forsyth p = f->buf->data;
235337da2899SCharles.Forsyth
235437da2899SCharles.Forsyth for(i = 8; i <= f->n; i += 8, p += 8)
235537da2899SCharles.Forsyth block_cipher(ds->state.expanded, p, f->direction);
235637da2899SCharles.Forsyth }
235737da2899SCharles.Forsyth
235837da2899SCharles.Forsyth void
Keyring_descbc(void * fp)235937da2899SCharles.Forsyth Keyring_descbc(void *fp)
236037da2899SCharles.Forsyth {
236137da2899SCharles.Forsyth F_Keyring_descbc *f;
236237da2899SCharles.Forsyth XDESstate *ds;
236337da2899SCharles.Forsyth uchar *p, *ep, *ip, *p2, *eip;
236437da2899SCharles.Forsyth uchar tmp[8];
236537da2899SCharles.Forsyth
236637da2899SCharles.Forsyth f = fp;
236737da2899SCharles.Forsyth
2368ca1042d3SCharles.Forsyth if(f->buf == H)
236937da2899SCharles.Forsyth return;
23709bca6be9Sforsyth if(f->n < 0 || f->n > f->buf->len)
23719bca6be9Sforsyth error(exBounds);
237237da2899SCharles.Forsyth if(f->n & 7)
2373132f29a5Sforsyth error(exBadBsize);
237437da2899SCharles.Forsyth
23759bca6be9Sforsyth ds = checktype(f->state, TDESstate, exBadState, 0);
237637da2899SCharles.Forsyth p = f->buf->data;
237737da2899SCharles.Forsyth
237837da2899SCharles.Forsyth if(f->direction == 0){
237937da2899SCharles.Forsyth for(ep = p + f->n; p < ep; p += 8){
238037da2899SCharles.Forsyth p2 = p;
238137da2899SCharles.Forsyth ip = ds->state.ivec;
238237da2899SCharles.Forsyth for(eip = ip+8; ip < eip; )
238337da2899SCharles.Forsyth *p2++ ^= *ip++;
238437da2899SCharles.Forsyth block_cipher(ds->state.expanded, p, 0);
238537da2899SCharles.Forsyth memmove(ds->state.ivec, p, 8);
238637da2899SCharles.Forsyth }
238737da2899SCharles.Forsyth } else {
238837da2899SCharles.Forsyth for(ep = p + f->n; p < ep; ){
238937da2899SCharles.Forsyth memmove(tmp, p, 8);
239037da2899SCharles.Forsyth block_cipher(ds->state.expanded, p, 1);
239137da2899SCharles.Forsyth p2 = tmp;
239237da2899SCharles.Forsyth ip = ds->state.ivec;
239337da2899SCharles.Forsyth for(eip = ip+8; ip < eip; ){
239437da2899SCharles.Forsyth *p++ ^= *ip;
239537da2899SCharles.Forsyth *ip++ = *p2++;
239637da2899SCharles.Forsyth }
239737da2899SCharles.Forsyth }
239837da2899SCharles.Forsyth }
239937da2899SCharles.Forsyth }
240037da2899SCharles.Forsyth
240137da2899SCharles.Forsyth void
Keyring_ideasetup(void * fp)240237da2899SCharles.Forsyth Keyring_ideasetup(void *fp)
240337da2899SCharles.Forsyth {
240437da2899SCharles.Forsyth F_Keyring_ideasetup *f;
240537da2899SCharles.Forsyth Heap *h;
240637da2899SCharles.Forsyth XIDEAstate *is;
240737da2899SCharles.Forsyth uchar *ivec;
24089bca6be9Sforsyth void *r;
240937da2899SCharles.Forsyth
241037da2899SCharles.Forsyth f = fp;
24119bca6be9Sforsyth r = *f->ret;
241237da2899SCharles.Forsyth *f->ret = H;
24139bca6be9Sforsyth destroy(r);
241437da2899SCharles.Forsyth
2415132f29a5Sforsyth if(f->key == H || f->key->len < 16)
2416132f29a5Sforsyth error(exBadKey);
2417132f29a5Sforsyth if(f->ivec != H){
2418132f29a5Sforsyth if(f->ivec->len < 8)
2419132f29a5Sforsyth error(exBadIvec);
242037da2899SCharles.Forsyth ivec = f->ivec->data;
2421132f29a5Sforsyth }else
2422132f29a5Sforsyth ivec = nil;
242337da2899SCharles.Forsyth
242437da2899SCharles.Forsyth h = heap(TIDEAstate);
242537da2899SCharles.Forsyth is = H2D(XIDEAstate*, h);
242637da2899SCharles.Forsyth
242737da2899SCharles.Forsyth setupIDEAstate(&is->state, f->key->data, ivec);
242837da2899SCharles.Forsyth
242937da2899SCharles.Forsyth *f->ret = (Keyring_IDEAstate*)is;
243037da2899SCharles.Forsyth }
243137da2899SCharles.Forsyth
243237da2899SCharles.Forsyth void
Keyring_ideaecb(void * fp)243337da2899SCharles.Forsyth Keyring_ideaecb(void *fp)
243437da2899SCharles.Forsyth {
243537da2899SCharles.Forsyth F_Keyring_ideaecb *f;
243637da2899SCharles.Forsyth XIDEAstate *is;
243737da2899SCharles.Forsyth int i;
243837da2899SCharles.Forsyth uchar *p;
243937da2899SCharles.Forsyth
244037da2899SCharles.Forsyth f = fp;
244137da2899SCharles.Forsyth
2442132f29a5Sforsyth if(f->buf == H)
244337da2899SCharles.Forsyth return;
24449bca6be9Sforsyth if(f->n < 0 || f->n > f->buf->len)
24459bca6be9Sforsyth error(exBounds);
244637da2899SCharles.Forsyth if(f->n & 7)
2447132f29a5Sforsyth error(exBadBsize);
244837da2899SCharles.Forsyth
24499bca6be9Sforsyth is = checktype(f->state, TIDEAstate, exBadState, 0);
245037da2899SCharles.Forsyth p = f->buf->data;
245137da2899SCharles.Forsyth
245237da2899SCharles.Forsyth for(i = 8; i <= f->n; i += 8, p += 8)
245337da2899SCharles.Forsyth idea_cipher(is->state.edkey, p, f->direction);
245437da2899SCharles.Forsyth }
245537da2899SCharles.Forsyth
245637da2899SCharles.Forsyth void
Keyring_ideacbc(void * fp)245737da2899SCharles.Forsyth Keyring_ideacbc(void *fp)
245837da2899SCharles.Forsyth {
245937da2899SCharles.Forsyth F_Keyring_ideacbc *f;
246037da2899SCharles.Forsyth XIDEAstate *is;
246137da2899SCharles.Forsyth uchar *p, *ep, *ip, *p2, *eip;
246237da2899SCharles.Forsyth uchar tmp[8];
246337da2899SCharles.Forsyth
246437da2899SCharles.Forsyth f = fp;
246537da2899SCharles.Forsyth
2466132f29a5Sforsyth if(f->buf == H)
246737da2899SCharles.Forsyth return;
24689bca6be9Sforsyth if(f->n < 0 || f->n > f->buf->len)
24699bca6be9Sforsyth error(exBounds);
247037da2899SCharles.Forsyth if(f->n & 7)
2471132f29a5Sforsyth error(exBadBsize);
247237da2899SCharles.Forsyth
24739bca6be9Sforsyth is = checktype(f->state, TIDEAstate, exBadState, 0);
247437da2899SCharles.Forsyth p = f->buf->data;
247537da2899SCharles.Forsyth
247637da2899SCharles.Forsyth if(f->direction == 0){
247737da2899SCharles.Forsyth for(ep = p + f->n; p < ep; p += 8){
247837da2899SCharles.Forsyth p2 = p;
247937da2899SCharles.Forsyth ip = is->state.ivec;
248037da2899SCharles.Forsyth for(eip = ip+8; ip < eip; )
248137da2899SCharles.Forsyth *p2++ ^= *ip++;
248237da2899SCharles.Forsyth idea_cipher(is->state.edkey, p, 0);
248337da2899SCharles.Forsyth memmove(is->state.ivec, p, 8);
248437da2899SCharles.Forsyth }
248537da2899SCharles.Forsyth } else {
248637da2899SCharles.Forsyth for(ep = p + f->n; p < ep; ){
248737da2899SCharles.Forsyth memmove(tmp, p, 8);
248837da2899SCharles.Forsyth idea_cipher(is->state.edkey, p, 1);
248937da2899SCharles.Forsyth p2 = tmp;
249037da2899SCharles.Forsyth ip = is->state.ivec;
249137da2899SCharles.Forsyth for(eip = ip+8; ip < eip; ){
249237da2899SCharles.Forsyth *p++ ^= *ip;
249337da2899SCharles.Forsyth *ip++ = *p2++;
249437da2899SCharles.Forsyth }
249537da2899SCharles.Forsyth }
249637da2899SCharles.Forsyth }
249737da2899SCharles.Forsyth }
249837da2899SCharles.Forsyth
249937da2899SCharles.Forsyth void
Keyring_aessetup(void * fp)250037da2899SCharles.Forsyth Keyring_aessetup(void *fp)
250137da2899SCharles.Forsyth {
250237da2899SCharles.Forsyth F_Keyring_aessetup *f;
250337da2899SCharles.Forsyth Heap *h;
250437da2899SCharles.Forsyth XAESstate *is;
250537da2899SCharles.Forsyth uchar *ivec;
25069bca6be9Sforsyth void *r;
250737da2899SCharles.Forsyth
250837da2899SCharles.Forsyth f = fp;
25099bca6be9Sforsyth r = *f->ret;
251037da2899SCharles.Forsyth *f->ret = H;
25119bca6be9Sforsyth destroy(r);
251237da2899SCharles.Forsyth
2513132f29a5Sforsyth if(f->key == H ||
2514132f29a5Sforsyth f->key->len != 16 && f->key->len != 24 && f->key->len != 32)
2515132f29a5Sforsyth error(exBadKey);
2516132f29a5Sforsyth if(f->ivec != H){
2517132f29a5Sforsyth if(f->ivec->len < AESbsize)
2518132f29a5Sforsyth error(exBadIvec);
251937da2899SCharles.Forsyth ivec = f->ivec->data;
2520132f29a5Sforsyth }else
2521132f29a5Sforsyth ivec = nil;
252237da2899SCharles.Forsyth
252337da2899SCharles.Forsyth h = heap(TAESstate);
252437da2899SCharles.Forsyth is = H2D(XAESstate*, h);
252537da2899SCharles.Forsyth
252637da2899SCharles.Forsyth setupAESstate(&is->state, f->key->data, f->key->len, ivec);
252737da2899SCharles.Forsyth
252837da2899SCharles.Forsyth *f->ret = (Keyring_AESstate*)is;
252937da2899SCharles.Forsyth }
253037da2899SCharles.Forsyth
253137da2899SCharles.Forsyth void
Keyring_aescbc(void * fp)253237da2899SCharles.Forsyth Keyring_aescbc(void *fp)
253337da2899SCharles.Forsyth {
253437da2899SCharles.Forsyth F_Keyring_aescbc *f;
253537da2899SCharles.Forsyth XAESstate *is;
253637da2899SCharles.Forsyth uchar *p;
253737da2899SCharles.Forsyth
253837da2899SCharles.Forsyth f = fp;
253937da2899SCharles.Forsyth
2540132f29a5Sforsyth if(f->buf == H)
254137da2899SCharles.Forsyth return;
25429bca6be9Sforsyth if(f->n < 0 || f->n > f->buf->len)
25439bca6be9Sforsyth error(exBounds);
254437da2899SCharles.Forsyth
25459bca6be9Sforsyth is = checktype(f->state, TAESstate, exBadState, 0);
254637da2899SCharles.Forsyth p = f->buf->data;
254737da2899SCharles.Forsyth
254837da2899SCharles.Forsyth if(f->direction == 0)
254937da2899SCharles.Forsyth aesCBCencrypt(p, f->n, &is->state);
255037da2899SCharles.Forsyth else
255137da2899SCharles.Forsyth aesCBCdecrypt(p, f->n, &is->state);
255237da2899SCharles.Forsyth }
255337da2899SCharles.Forsyth
255437da2899SCharles.Forsyth void
Keyring_blowfishsetup(void * fp)2555ca1042d3SCharles.Forsyth Keyring_blowfishsetup(void *fp)
2556ca1042d3SCharles.Forsyth {
2557ca1042d3SCharles.Forsyth F_Keyring_blowfishsetup *f;
2558ca1042d3SCharles.Forsyth Heap *h;
2559ca1042d3SCharles.Forsyth XBFstate *is;
2560ca1042d3SCharles.Forsyth uchar *ivec;
25619bca6be9Sforsyth void *r;
2562ca1042d3SCharles.Forsyth
2563ca1042d3SCharles.Forsyth f = fp;
25649bca6be9Sforsyth r = *f->ret;
2565ca1042d3SCharles.Forsyth *f->ret = H;
25669bca6be9Sforsyth destroy(r);
2567ca1042d3SCharles.Forsyth
2568132f29a5Sforsyth if(f->key == H || f->key->len <= 0)
2569132f29a5Sforsyth error(exBadKey);
2570132f29a5Sforsyth if(f->ivec != H){
2571132f29a5Sforsyth if(f->ivec->len != BFbsize)
2572132f29a5Sforsyth error(exBadIvec);
2573ca1042d3SCharles.Forsyth ivec = f->ivec->data;
2574132f29a5Sforsyth }else
2575132f29a5Sforsyth ivec = nil;
2576ca1042d3SCharles.Forsyth
2577ca1042d3SCharles.Forsyth h = heap(TBFstate);
2578ca1042d3SCharles.Forsyth is = H2D(XBFstate*, h);
2579ca1042d3SCharles.Forsyth
2580ca1042d3SCharles.Forsyth setupBFstate(&is->state, f->key->data, f->key->len, ivec);
2581ca1042d3SCharles.Forsyth
2582ca1042d3SCharles.Forsyth *f->ret = (Keyring_BFstate*)is;
2583ca1042d3SCharles.Forsyth }
2584ca1042d3SCharles.Forsyth
2585ca1042d3SCharles.Forsyth void
Keyring_blowfishcbc(void * fp)2586ca1042d3SCharles.Forsyth Keyring_blowfishcbc(void *fp)
2587ca1042d3SCharles.Forsyth {
2588ca1042d3SCharles.Forsyth F_Keyring_blowfishcbc *f;
2589ca1042d3SCharles.Forsyth XBFstate *is;
2590ca1042d3SCharles.Forsyth uchar *p;
2591ca1042d3SCharles.Forsyth
2592ca1042d3SCharles.Forsyth f = fp;
2593ca1042d3SCharles.Forsyth
2594132f29a5Sforsyth if(f->buf == H)
2595ca1042d3SCharles.Forsyth return;
25969bca6be9Sforsyth if(f->n < 0 || f->n > f->buf->len)
25979bca6be9Sforsyth error(exBounds);
25989bca6be9Sforsyth if(f->n & 7)
25999bca6be9Sforsyth error(exBadBsize);
2600ca1042d3SCharles.Forsyth
26019bca6be9Sforsyth is = checktype(f->state, TBFstate, exBadState, 0);
2602ca1042d3SCharles.Forsyth p = f->buf->data;
2603ca1042d3SCharles.Forsyth
2604ca1042d3SCharles.Forsyth if(f->direction == 0)
2605ca1042d3SCharles.Forsyth bfCBCencrypt(p, f->n, &is->state);
2606ca1042d3SCharles.Forsyth else
2607ca1042d3SCharles.Forsyth bfCBCdecrypt(p, f->n, &is->state);
2608ca1042d3SCharles.Forsyth }
2609ca1042d3SCharles.Forsyth
2610ca1042d3SCharles.Forsyth void
Keyring_rc4setup(void * fp)261137da2899SCharles.Forsyth Keyring_rc4setup(void *fp)
261237da2899SCharles.Forsyth {
261337da2899SCharles.Forsyth F_Keyring_rc4setup *f;
261437da2899SCharles.Forsyth Heap *h;
261537da2899SCharles.Forsyth XRC4state *is;
26169bca6be9Sforsyth void *r;
261737da2899SCharles.Forsyth
261837da2899SCharles.Forsyth f = fp;
26199bca6be9Sforsyth r = *f->ret;
262037da2899SCharles.Forsyth *f->ret = H;
26219bca6be9Sforsyth destroy(r);
262237da2899SCharles.Forsyth
2623132f29a5Sforsyth if(f->seed == H)
262437da2899SCharles.Forsyth return;
262537da2899SCharles.Forsyth
262637da2899SCharles.Forsyth h = heap(TRC4state);
262737da2899SCharles.Forsyth is = H2D(XRC4state*, h);
262837da2899SCharles.Forsyth
262937da2899SCharles.Forsyth setupRC4state(&is->state, f->seed->data, f->seed->len);
263037da2899SCharles.Forsyth
263137da2899SCharles.Forsyth *f->ret = (Keyring_RC4state*)is;
263237da2899SCharles.Forsyth }
263337da2899SCharles.Forsyth
263437da2899SCharles.Forsyth void
Keyring_rc4(void * fp)263537da2899SCharles.Forsyth Keyring_rc4(void *fp)
263637da2899SCharles.Forsyth {
263737da2899SCharles.Forsyth F_Keyring_rc4 *f;
263837da2899SCharles.Forsyth XRC4state *is;
263937da2899SCharles.Forsyth uchar *p;
264037da2899SCharles.Forsyth
264137da2899SCharles.Forsyth f = fp;
2642132f29a5Sforsyth if(f->buf == H)
264337da2899SCharles.Forsyth return;
26449bca6be9Sforsyth if(f->n < 0 || f->n > f->buf->len)
26459bca6be9Sforsyth error(exBounds);
26469bca6be9Sforsyth is = checktype(f->state, TRC4state, exBadState, 0);
264737da2899SCharles.Forsyth p = f->buf->data;
264837da2899SCharles.Forsyth rc4(&is->state, p, f->n);
264937da2899SCharles.Forsyth }
265037da2899SCharles.Forsyth
265137da2899SCharles.Forsyth void
Keyring_rc4skip(void * fp)265237da2899SCharles.Forsyth Keyring_rc4skip(void *fp)
265337da2899SCharles.Forsyth {
265437da2899SCharles.Forsyth F_Keyring_rc4skip *f;
265537da2899SCharles.Forsyth XRC4state *is;
265637da2899SCharles.Forsyth
265737da2899SCharles.Forsyth f = fp;
26589bca6be9Sforsyth is = checktype(f->state, TRC4state, exBadState, 0);
265937da2899SCharles.Forsyth rc4skip(&is->state, f->n);
266037da2899SCharles.Forsyth }
266137da2899SCharles.Forsyth
266237da2899SCharles.Forsyth void
Keyring_rc4back(void * fp)266337da2899SCharles.Forsyth Keyring_rc4back(void *fp)
266437da2899SCharles.Forsyth {
266537da2899SCharles.Forsyth F_Keyring_rc4back *f;
266637da2899SCharles.Forsyth XRC4state *is;
266737da2899SCharles.Forsyth
266837da2899SCharles.Forsyth f = fp;
26699bca6be9Sforsyth is = checktype(f->state, TRC4state, exBadState, 0);
267037da2899SCharles.Forsyth rc4back(&is->state, f->n);
267137da2899SCharles.Forsyth }
2672ca1042d3SCharles.Forsyth
2673ca1042d3SCharles.Forsyth /*
2674ca1042d3SCharles.Forsyth * public/secret keys, signing and verifying
2675ca1042d3SCharles.Forsyth */
2676ca1042d3SCharles.Forsyth
2677ca1042d3SCharles.Forsyth static void
dsapk2pub(DSApub * p,Keyring_DSApk * pk)2678ca1042d3SCharles.Forsyth dsapk2pub(DSApub* p, Keyring_DSApk* pk)
2679ca1042d3SCharles.Forsyth {
2680ca1042d3SCharles.Forsyth if(pk == H)
2681ca1042d3SCharles.Forsyth error(exNilref);
2682ca1042d3SCharles.Forsyth p->p = checkIPint(pk->p);
2683ca1042d3SCharles.Forsyth p->q = checkIPint(pk->q);
2684ca1042d3SCharles.Forsyth p->alpha = checkIPint(pk->alpha);
2685ca1042d3SCharles.Forsyth p->key = checkIPint(pk->key);
2686ca1042d3SCharles.Forsyth }
2687ca1042d3SCharles.Forsyth
2688ca1042d3SCharles.Forsyth static void
dsask2priv(DSApriv * p,Keyring_DSAsk * sk)2689ca1042d3SCharles.Forsyth dsask2priv(DSApriv* p, Keyring_DSAsk* sk)
2690ca1042d3SCharles.Forsyth {
2691ca1042d3SCharles.Forsyth if(sk == H || sk->pk == H)
2692ca1042d3SCharles.Forsyth error(exNilref);
2693ca1042d3SCharles.Forsyth dsapk2pub(&p->pub, sk->pk);
2694ca1042d3SCharles.Forsyth p->secret = checkIPint(sk->secret);
2695ca1042d3SCharles.Forsyth }
2696ca1042d3SCharles.Forsyth
2697ca1042d3SCharles.Forsyth static void
dsapriv2sk(Keyring_DSAsk * sk,DSApriv * p)2698ca1042d3SCharles.Forsyth dsapriv2sk(Keyring_DSAsk* sk, DSApriv* p)
2699ca1042d3SCharles.Forsyth {
2700ca1042d3SCharles.Forsyth Keyring_DSApk* pk;
2701ca1042d3SCharles.Forsyth
2702ca1042d3SCharles.Forsyth pk = sk->pk;
2703ca1042d3SCharles.Forsyth pk->p = ipcopymp(p->pub.p);
2704ca1042d3SCharles.Forsyth pk->q = ipcopymp(p->pub.q);
2705ca1042d3SCharles.Forsyth pk->alpha = ipcopymp(p->pub.alpha);
2706ca1042d3SCharles.Forsyth pk->key = ipcopymp(p->pub.key);
2707ca1042d3SCharles.Forsyth sk->secret = ipcopymp(p->secret);
2708ca1042d3SCharles.Forsyth }
2709ca1042d3SCharles.Forsyth
2710ca1042d3SCharles.Forsyth void
DSAsk_gen(void * fp)2711ca1042d3SCharles.Forsyth DSAsk_gen(void *fp)
2712ca1042d3SCharles.Forsyth {
2713ca1042d3SCharles.Forsyth F_DSAsk_gen *f;
2714ca1042d3SCharles.Forsyth Keyring_DSAsk *sk;
2715ca1042d3SCharles.Forsyth DSApriv *p;
2716ca1042d3SCharles.Forsyth DSApub pub, *oldpk;
2717ca1042d3SCharles.Forsyth void *v;
2718ca1042d3SCharles.Forsyth
2719ca1042d3SCharles.Forsyth f = fp;
2720ca1042d3SCharles.Forsyth v = *f->ret;
2721ca1042d3SCharles.Forsyth sk = newthing(TDSAsk, 0);
2722ca1042d3SCharles.Forsyth sk->pk = newthing(TDSApk, 0);
2723ca1042d3SCharles.Forsyth *f->ret = sk;
2724ca1042d3SCharles.Forsyth destroy(v);
2725ca1042d3SCharles.Forsyth oldpk = nil;
2726ca1042d3SCharles.Forsyth if(f->oldpk != H){
2727ca1042d3SCharles.Forsyth dsapk2pub(&pub, f->oldpk);
2728ca1042d3SCharles.Forsyth oldpk = &pub;
2729ca1042d3SCharles.Forsyth }
2730ca1042d3SCharles.Forsyth release();
2731ca1042d3SCharles.Forsyth p = dsagen(oldpk);
2732ca1042d3SCharles.Forsyth acquire();
2733ca1042d3SCharles.Forsyth dsapriv2sk(sk, p);
2734ca1042d3SCharles.Forsyth dsaprivfree(p);
2735ca1042d3SCharles.Forsyth }
2736ca1042d3SCharles.Forsyth
2737ca1042d3SCharles.Forsyth void
DSAsk_sign(void * fp)2738ca1042d3SCharles.Forsyth DSAsk_sign(void *fp)
2739ca1042d3SCharles.Forsyth {
2740ca1042d3SCharles.Forsyth F_DSAsk_sign *f;
2741ca1042d3SCharles.Forsyth Keyring_DSAsig *sig;
2742ca1042d3SCharles.Forsyth DSApriv p;
274331a18a69SCharles.Forsyth mpint *m;
2744ca1042d3SCharles.Forsyth DSAsig *s;
2745ca1042d3SCharles.Forsyth void *v;
2746ca1042d3SCharles.Forsyth
2747ca1042d3SCharles.Forsyth f = fp;
2748ca1042d3SCharles.Forsyth v = *f->ret;
2749ca1042d3SCharles.Forsyth sig = newthing(TDSAsig, 0);
2750ca1042d3SCharles.Forsyth *f->ret = sig;
2751ca1042d3SCharles.Forsyth destroy(v);
2752ca1042d3SCharles.Forsyth
2753ca1042d3SCharles.Forsyth dsask2priv(&p, f->k);
2754ca1042d3SCharles.Forsyth m = checkIPint(f->m);
2755ca1042d3SCharles.Forsyth release();
2756ca1042d3SCharles.Forsyth s = dsasign(&p, m);
2757ca1042d3SCharles.Forsyth acquire();
2758ca1042d3SCharles.Forsyth sig->r = ipcopymp(s->r);
2759ca1042d3SCharles.Forsyth sig->s = ipcopymp(s->s);
2760ca1042d3SCharles.Forsyth dsasigfree(s);
2761ca1042d3SCharles.Forsyth }
2762ca1042d3SCharles.Forsyth
2763ca1042d3SCharles.Forsyth void
DSApk_verify(void * fp)2764ca1042d3SCharles.Forsyth DSApk_verify(void *fp)
2765ca1042d3SCharles.Forsyth {
2766ca1042d3SCharles.Forsyth F_DSApk_verify *f;
2767ca1042d3SCharles.Forsyth DSApub p;
2768ca1042d3SCharles.Forsyth DSAsig sig;
276931a18a69SCharles.Forsyth mpint *m;
2770ca1042d3SCharles.Forsyth
2771ca1042d3SCharles.Forsyth f = fp;
2772ca1042d3SCharles.Forsyth *f->ret = 0;
2773ca1042d3SCharles.Forsyth if(f->m == H || f->sig == H)
2774ca1042d3SCharles.Forsyth return;
2775ca1042d3SCharles.Forsyth dsapk2pub(&p, f->k);
2776ca1042d3SCharles.Forsyth sig.r = checkIPint(f->sig->r);
2777ca1042d3SCharles.Forsyth sig.s = checkIPint(f->sig->s);
2778ca1042d3SCharles.Forsyth m = checkIPint(f->m);
2779ca1042d3SCharles.Forsyth release();
2780ca1042d3SCharles.Forsyth *f->ret = dsaverify(&p, &sig, m) == 0;
2781ca1042d3SCharles.Forsyth acquire();
2782ca1042d3SCharles.Forsyth }
2783ca1042d3SCharles.Forsyth
2784ca1042d3SCharles.Forsyth static void
egpk2pub(EGpub * p,Keyring_EGpk * pk)2785ca1042d3SCharles.Forsyth egpk2pub(EGpub* p, Keyring_EGpk* pk)
2786ca1042d3SCharles.Forsyth {
2787ca1042d3SCharles.Forsyth if(pk == H)
2788ca1042d3SCharles.Forsyth error(exNilref);
2789ca1042d3SCharles.Forsyth p->p = checkIPint(pk->p);
2790ca1042d3SCharles.Forsyth p->alpha = checkIPint(pk->alpha);
2791ca1042d3SCharles.Forsyth p->key = checkIPint(pk->key);
2792ca1042d3SCharles.Forsyth }
2793ca1042d3SCharles.Forsyth
2794ca1042d3SCharles.Forsyth static void
egsk2priv(EGpriv * p,Keyring_EGsk * sk)2795ca1042d3SCharles.Forsyth egsk2priv(EGpriv* p, Keyring_EGsk* sk)
2796ca1042d3SCharles.Forsyth {
2797ca1042d3SCharles.Forsyth if(sk == H || sk->pk == H)
2798ca1042d3SCharles.Forsyth error(exNilref);
2799ca1042d3SCharles.Forsyth egpk2pub(&p->pub, sk->pk);
2800ca1042d3SCharles.Forsyth p->secret = checkIPint(sk->secret);
2801ca1042d3SCharles.Forsyth }
2802ca1042d3SCharles.Forsyth
2803ca1042d3SCharles.Forsyth static void
egpriv2sk(Keyring_EGsk * sk,EGpriv * p)2804ca1042d3SCharles.Forsyth egpriv2sk(Keyring_EGsk* sk, EGpriv* p)
2805ca1042d3SCharles.Forsyth {
2806ca1042d3SCharles.Forsyth Keyring_EGpk* pk;
2807ca1042d3SCharles.Forsyth
2808ca1042d3SCharles.Forsyth pk = sk->pk;
2809ca1042d3SCharles.Forsyth pk->p = ipcopymp(p->pub.p);
2810ca1042d3SCharles.Forsyth pk->alpha = ipcopymp(p->pub.alpha);
2811ca1042d3SCharles.Forsyth pk->key = ipcopymp(p->pub.key);
2812ca1042d3SCharles.Forsyth sk->secret = ipcopymp(p->secret);
2813ca1042d3SCharles.Forsyth }
2814ca1042d3SCharles.Forsyth
2815ca1042d3SCharles.Forsyth void
EGsk_gen(void * fp)2816ca1042d3SCharles.Forsyth EGsk_gen(void *fp)
2817ca1042d3SCharles.Forsyth {
2818ca1042d3SCharles.Forsyth F_EGsk_gen *f;
2819ca1042d3SCharles.Forsyth Keyring_EGsk *sk;
2820ca1042d3SCharles.Forsyth EGpriv *p;
2821ca1042d3SCharles.Forsyth void *v;
2822ca1042d3SCharles.Forsyth
2823ca1042d3SCharles.Forsyth f = fp;
2824ca1042d3SCharles.Forsyth v = *f->ret;
2825ca1042d3SCharles.Forsyth sk = newthing(TEGsk, 0);
2826ca1042d3SCharles.Forsyth sk->pk = newthing(TEGpk, 0);
2827ca1042d3SCharles.Forsyth *f->ret = sk;
2828ca1042d3SCharles.Forsyth destroy(v);
2829ca1042d3SCharles.Forsyth release();
2830ca1042d3SCharles.Forsyth for(;;){
2831ca1042d3SCharles.Forsyth p = eggen(f->nlen, f->nrep);
2832ca1042d3SCharles.Forsyth if(mpsignif(p->pub.p) == f->nlen)
2833ca1042d3SCharles.Forsyth break;
2834ca1042d3SCharles.Forsyth egprivfree(p);
2835ca1042d3SCharles.Forsyth }
2836ca1042d3SCharles.Forsyth acquire();
2837ca1042d3SCharles.Forsyth egpriv2sk(sk, p);
2838ca1042d3SCharles.Forsyth egprivfree(p);
2839ca1042d3SCharles.Forsyth }
2840ca1042d3SCharles.Forsyth
2841ca1042d3SCharles.Forsyth void
EGsk_sign(void * fp)2842ca1042d3SCharles.Forsyth EGsk_sign(void *fp)
2843ca1042d3SCharles.Forsyth {
2844ca1042d3SCharles.Forsyth F_EGsk_sign *f;
2845ca1042d3SCharles.Forsyth Keyring_EGsig *sig;
2846ca1042d3SCharles.Forsyth EGpriv p;
284731a18a69SCharles.Forsyth mpint *m;
2848ca1042d3SCharles.Forsyth EGsig *s;
2849ca1042d3SCharles.Forsyth void *v;
2850ca1042d3SCharles.Forsyth
2851ca1042d3SCharles.Forsyth f = fp;
2852ca1042d3SCharles.Forsyth v = *f->ret;
2853ca1042d3SCharles.Forsyth sig = newthing(TEGsig, 0);
2854ca1042d3SCharles.Forsyth *f->ret = sig;
2855ca1042d3SCharles.Forsyth destroy(v);
2856ca1042d3SCharles.Forsyth
2857ca1042d3SCharles.Forsyth egsk2priv(&p, f->k);
2858ca1042d3SCharles.Forsyth m = checkIPint(f->m);
2859ca1042d3SCharles.Forsyth release();
2860ca1042d3SCharles.Forsyth s = egsign(&p, m);
2861ca1042d3SCharles.Forsyth acquire();
2862ca1042d3SCharles.Forsyth sig->r = ipcopymp(s->r);
2863ca1042d3SCharles.Forsyth sig->s = ipcopymp(s->s);
2864ca1042d3SCharles.Forsyth egsigfree(s);
2865ca1042d3SCharles.Forsyth }
2866ca1042d3SCharles.Forsyth
2867ca1042d3SCharles.Forsyth void
EGpk_verify(void * fp)2868ca1042d3SCharles.Forsyth EGpk_verify(void *fp)
2869ca1042d3SCharles.Forsyth {
2870ca1042d3SCharles.Forsyth F_EGpk_verify *f;
2871ca1042d3SCharles.Forsyth EGpub p;
2872ca1042d3SCharles.Forsyth EGsig sig;
287331a18a69SCharles.Forsyth mpint *m;
2874ca1042d3SCharles.Forsyth
2875ca1042d3SCharles.Forsyth f = fp;
2876ca1042d3SCharles.Forsyth *f->ret = 0;
2877ca1042d3SCharles.Forsyth if(f->m == H || f->sig == H)
2878ca1042d3SCharles.Forsyth return;
2879ca1042d3SCharles.Forsyth egpk2pub(&p, f->k);
2880ca1042d3SCharles.Forsyth sig.r = checkIPint(f->sig->r);
2881ca1042d3SCharles.Forsyth sig.s = checkIPint(f->sig->s);
2882ca1042d3SCharles.Forsyth m = checkIPint(f->m);
2883ca1042d3SCharles.Forsyth release();
2884ca1042d3SCharles.Forsyth *f->ret = egverify(&p, &sig, m) == 0;
2885ca1042d3SCharles.Forsyth acquire();
2886ca1042d3SCharles.Forsyth }
2887ca1042d3SCharles.Forsyth
2888ca1042d3SCharles.Forsyth static void
rsapk2pub(RSApub * p,Keyring_RSApk * pk)2889ca1042d3SCharles.Forsyth rsapk2pub(RSApub* p, Keyring_RSApk* pk)
2890ca1042d3SCharles.Forsyth {
2891ca1042d3SCharles.Forsyth if(pk == H)
2892ca1042d3SCharles.Forsyth error(exNilref);
2893ca1042d3SCharles.Forsyth memset(p, 0, sizeof(*p));
2894ca1042d3SCharles.Forsyth p->n = checkIPint(pk->n);
2895ca1042d3SCharles.Forsyth p->ek = checkIPint(pk->ek);
2896ca1042d3SCharles.Forsyth }
2897ca1042d3SCharles.Forsyth
2898ca1042d3SCharles.Forsyth static void
rsask2priv(RSApriv * p,Keyring_RSAsk * sk)2899ca1042d3SCharles.Forsyth rsask2priv(RSApriv* p, Keyring_RSAsk* sk)
2900ca1042d3SCharles.Forsyth {
2901ca1042d3SCharles.Forsyth if(sk == H || sk->pk == H)
2902ca1042d3SCharles.Forsyth error(exNilref);
2903ca1042d3SCharles.Forsyth rsapk2pub(&p->pub, sk->pk);
2904ca1042d3SCharles.Forsyth p->dk = checkIPint(sk->dk);
2905ca1042d3SCharles.Forsyth p->p = checkIPint(sk->p);
2906ca1042d3SCharles.Forsyth p->q = checkIPint(sk->q);
2907ca1042d3SCharles.Forsyth p->kp = checkIPint(sk->kp);
2908ca1042d3SCharles.Forsyth p->kq = checkIPint(sk->kq);
2909ca1042d3SCharles.Forsyth p->c2 = checkIPint(sk->c2);
2910ca1042d3SCharles.Forsyth }
2911ca1042d3SCharles.Forsyth
2912ca1042d3SCharles.Forsyth static void
rsapriv2sk(Keyring_RSAsk * sk,RSApriv * p)2913ca1042d3SCharles.Forsyth rsapriv2sk(Keyring_RSAsk* sk, RSApriv* p)
2914ca1042d3SCharles.Forsyth {
2915ca1042d3SCharles.Forsyth Keyring_RSApk* pk;
2916ca1042d3SCharles.Forsyth
2917ca1042d3SCharles.Forsyth pk = sk->pk;
2918ca1042d3SCharles.Forsyth pk->n = ipcopymp(p->pub.n);
2919ca1042d3SCharles.Forsyth pk->ek = ipcopymp(p->pub.ek);
2920ca1042d3SCharles.Forsyth sk->dk = ipcopymp(p->dk);
2921ca1042d3SCharles.Forsyth sk->p = ipcopymp(p->p);
2922ca1042d3SCharles.Forsyth sk->q = ipcopymp(p->q);
2923ca1042d3SCharles.Forsyth sk->kp = ipcopymp(p->kp);
2924ca1042d3SCharles.Forsyth sk->kq = ipcopymp(p->kq);
2925ca1042d3SCharles.Forsyth sk->c2 = ipcopymp(p->c2);
2926ca1042d3SCharles.Forsyth }
2927ca1042d3SCharles.Forsyth
2928ca1042d3SCharles.Forsyth void
RSApk_encrypt(void * fp)2929ca1042d3SCharles.Forsyth RSApk_encrypt(void *fp)
2930ca1042d3SCharles.Forsyth {
2931ca1042d3SCharles.Forsyth F_RSApk_encrypt *f;
2932ca1042d3SCharles.Forsyth RSApub p;
293331a18a69SCharles.Forsyth mpint *m, *o;
2934ca1042d3SCharles.Forsyth void *v;
2935ca1042d3SCharles.Forsyth
2936ca1042d3SCharles.Forsyth f = fp;
2937ca1042d3SCharles.Forsyth v = *f->ret;
2938ca1042d3SCharles.Forsyth *f->ret = H;
2939ca1042d3SCharles.Forsyth destroy(v);
2940ca1042d3SCharles.Forsyth
2941ca1042d3SCharles.Forsyth rsapk2pub(&p, f->k);
2942ca1042d3SCharles.Forsyth m = checkIPint(f->m);
2943ca1042d3SCharles.Forsyth release();
2944ca1042d3SCharles.Forsyth o = rsaencrypt(&p, m, nil);
2945ca1042d3SCharles.Forsyth acquire();
2946ca1042d3SCharles.Forsyth *f->ret = newIPint(o);
2947ca1042d3SCharles.Forsyth }
2948ca1042d3SCharles.Forsyth
2949ca1042d3SCharles.Forsyth void
RSAsk_gen(void * fp)2950ca1042d3SCharles.Forsyth RSAsk_gen(void *fp)
2951ca1042d3SCharles.Forsyth {
2952ca1042d3SCharles.Forsyth F_RSAsk_gen *f;
2953ca1042d3SCharles.Forsyth Keyring_RSAsk *sk;
2954ca1042d3SCharles.Forsyth RSApriv *p;
2955ca1042d3SCharles.Forsyth void *v;
2956ca1042d3SCharles.Forsyth
2957ca1042d3SCharles.Forsyth f = fp;
2958ca1042d3SCharles.Forsyth v = *f->ret;
2959ca1042d3SCharles.Forsyth sk = newthing(TRSAsk, 0);
2960ca1042d3SCharles.Forsyth sk->pk = newthing(TRSApk, 0);
2961ca1042d3SCharles.Forsyth *f->ret = sk;
2962ca1042d3SCharles.Forsyth destroy(v);
2963ca1042d3SCharles.Forsyth release();
2964ca1042d3SCharles.Forsyth for(;;){
2965ca1042d3SCharles.Forsyth p = rsagen(f->nlen, f->elen, f->nrep);
2966ca1042d3SCharles.Forsyth if(mpsignif(p->pub.n) == f->nlen)
2967ca1042d3SCharles.Forsyth break;
2968ca1042d3SCharles.Forsyth rsaprivfree(p);
2969ca1042d3SCharles.Forsyth }
2970ca1042d3SCharles.Forsyth acquire();
2971ca1042d3SCharles.Forsyth rsapriv2sk(sk, p);
2972ca1042d3SCharles.Forsyth rsaprivfree(p);
2973ca1042d3SCharles.Forsyth }
2974ca1042d3SCharles.Forsyth
2975ca1042d3SCharles.Forsyth void
RSAsk_fill(void * fp)2976ca1042d3SCharles.Forsyth RSAsk_fill(void *fp)
2977ca1042d3SCharles.Forsyth {
2978ca1042d3SCharles.Forsyth F_RSAsk_fill *f;
2979ca1042d3SCharles.Forsyth Keyring_RSAsk *sk;
2980ca1042d3SCharles.Forsyth RSApriv *p;
2981ca1042d3SCharles.Forsyth void *v;
2982ca1042d3SCharles.Forsyth
2983ca1042d3SCharles.Forsyth f = fp;
2984ca1042d3SCharles.Forsyth v = *f->ret;
2985ca1042d3SCharles.Forsyth sk = newthing(TRSAsk, 0);
2986ca1042d3SCharles.Forsyth sk->pk = newthing(TRSApk, 0);
2987ca1042d3SCharles.Forsyth *f->ret = sk;
2988ca1042d3SCharles.Forsyth destroy(v);
2989ca1042d3SCharles.Forsyth release();
2990ca1042d3SCharles.Forsyth p = rsafill(checkIPint(f->n), checkIPint(f->e), checkIPint(f->d),
2991ca1042d3SCharles.Forsyth checkIPint(f->p), checkIPint(f->q));
2992ca1042d3SCharles.Forsyth acquire();
2993ca1042d3SCharles.Forsyth if(p == nil) {
2994ca1042d3SCharles.Forsyth *f->ret = H;
2995ca1042d3SCharles.Forsyth destroy(sk);
2996ca1042d3SCharles.Forsyth }else{
2997ca1042d3SCharles.Forsyth rsapriv2sk(sk, p);
2998ca1042d3SCharles.Forsyth rsaprivfree(p);
2999ca1042d3SCharles.Forsyth }
3000ca1042d3SCharles.Forsyth }
3001ca1042d3SCharles.Forsyth
3002ca1042d3SCharles.Forsyth void
RSAsk_decrypt(void * fp)3003ca1042d3SCharles.Forsyth RSAsk_decrypt(void *fp)
3004ca1042d3SCharles.Forsyth {
3005ca1042d3SCharles.Forsyth F_RSAsk_decrypt *f;
3006ca1042d3SCharles.Forsyth RSApriv p;
300731a18a69SCharles.Forsyth mpint *m, *o;
3008ca1042d3SCharles.Forsyth void *v;
3009ca1042d3SCharles.Forsyth
3010ca1042d3SCharles.Forsyth f = fp;
3011ca1042d3SCharles.Forsyth v = *f->ret;
3012ca1042d3SCharles.Forsyth *f->ret = H;
3013ca1042d3SCharles.Forsyth destroy(v);
3014ca1042d3SCharles.Forsyth
3015ca1042d3SCharles.Forsyth rsask2priv(&p, f->k);
3016ca1042d3SCharles.Forsyth m = checkIPint(f->m);
3017ca1042d3SCharles.Forsyth release();
3018ca1042d3SCharles.Forsyth o = rsadecrypt(&p, m, nil);
3019ca1042d3SCharles.Forsyth acquire();
3020ca1042d3SCharles.Forsyth *f->ret = newIPint(o);
3021ca1042d3SCharles.Forsyth }
3022ca1042d3SCharles.Forsyth
3023ca1042d3SCharles.Forsyth void
RSAsk_sign(void * fp)3024ca1042d3SCharles.Forsyth RSAsk_sign(void *fp)
3025ca1042d3SCharles.Forsyth {
3026ca1042d3SCharles.Forsyth F_RSAsk_sign *f;
3027ca1042d3SCharles.Forsyth Keyring_RSAsig *sig;
3028ca1042d3SCharles.Forsyth RSApriv p;
302931a18a69SCharles.Forsyth mpint *m, *s;
3030ca1042d3SCharles.Forsyth void *v;
3031ca1042d3SCharles.Forsyth
3032ca1042d3SCharles.Forsyth f = fp;
3033ca1042d3SCharles.Forsyth v = *f->ret;
3034ca1042d3SCharles.Forsyth sig = newthing(TRSAsig, 0);
3035ca1042d3SCharles.Forsyth *f->ret = sig;
3036ca1042d3SCharles.Forsyth destroy(v);
3037ca1042d3SCharles.Forsyth
3038ca1042d3SCharles.Forsyth rsask2priv(&p, f->k);
3039ca1042d3SCharles.Forsyth m = checkIPint(f->m);
3040ca1042d3SCharles.Forsyth release();
3041ca1042d3SCharles.Forsyth s = rsadecrypt(&p, m, nil);
3042ca1042d3SCharles.Forsyth acquire();
3043ca1042d3SCharles.Forsyth sig->n = newIPint(s);
3044ca1042d3SCharles.Forsyth }
3045ca1042d3SCharles.Forsyth
3046ca1042d3SCharles.Forsyth void
RSApk_verify(void * fp)3047ca1042d3SCharles.Forsyth RSApk_verify(void *fp)
3048ca1042d3SCharles.Forsyth {
3049ca1042d3SCharles.Forsyth F_RSApk_verify *f;
3050ca1042d3SCharles.Forsyth RSApub p;
305131a18a69SCharles.Forsyth mpint *sig, *m, *t;
3052ca1042d3SCharles.Forsyth
3053ca1042d3SCharles.Forsyth f = fp;
3054ca1042d3SCharles.Forsyth *f->ret = 0;
3055ca1042d3SCharles.Forsyth if(f->m == H || f->sig == H)
3056ca1042d3SCharles.Forsyth return;
3057ca1042d3SCharles.Forsyth rsapk2pub(&p, f->k);
3058ca1042d3SCharles.Forsyth sig = checkIPint(f->sig->n);
3059ca1042d3SCharles.Forsyth m = checkIPint(f->m);
3060ca1042d3SCharles.Forsyth release();
3061ca1042d3SCharles.Forsyth t = rsaencrypt(&p, sig, nil);
3062ca1042d3SCharles.Forsyth *f->ret = mpcmp(t, m) == 0;
3063ca1042d3SCharles.Forsyth mpfree(t);
3064ca1042d3SCharles.Forsyth acquire();
3065ca1042d3SCharles.Forsyth }
3066*7de2b42dSforsyth
3067*7de2b42dSforsyth void
Keyring_IPint_random(void * fp)3068*7de2b42dSforsyth Keyring_IPint_random(void *fp)
3069*7de2b42dSforsyth {
3070*7de2b42dSforsyth F_IPint_random *f;
3071*7de2b42dSforsyth mpint *b;
3072*7de2b42dSforsyth void *v;
3073*7de2b42dSforsyth
3074*7de2b42dSforsyth f = fp;
3075*7de2b42dSforsyth v = *f->ret;
3076*7de2b42dSforsyth *f->ret = H;
3077*7de2b42dSforsyth destroy(v);
3078*7de2b42dSforsyth
3079*7de2b42dSforsyth release();
3080*7de2b42dSforsyth b = mprand(f->maxbits, genrandom, nil);
3081*7de2b42dSforsyth acquire();
3082*7de2b42dSforsyth *f->ret = newIPint(b);
3083*7de2b42dSforsyth }
3084