From 0e43f5c6d330afe996e157205e78618001d1d038 Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Wed, 5 Oct 2011 16:20:59 -0400 Subject: dsasign: new command --- src/cmd/auth/dsasign.c | 180 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 180 insertions(+) create mode 100644 src/cmd/auth/dsasign.c (limited to 'src/cmd/auth/dsasign.c') diff --git a/src/cmd/auth/dsasign.c b/src/cmd/auth/dsasign.c new file mode 100644 index 00000000..1387dab6 --- /dev/null +++ b/src/cmd/auth/dsasign.c @@ -0,0 +1,180 @@ +#include +#include +#include +#include +#include +#include +#include <9pclient.h> +#include + +void +usage(void) +{ + fprint(2, "usage: 9 dsasign [-i id] [-v] key narg, rpc->arg); + threadexits(nil); +} + +static mpint* +keytomp(Attr *a, char *name) +{ + char *p; + mpint *m; + + p = _strfindattr(a, name); + if(p == nil) + sysfatal("missing key attribute %s", name); + m = strtomp(p, nil, 16, nil); + if(m == nil) + sysfatal("malformed key attribute %s=%s", name, p); + return m; +} + +static void +doVerify(void) +{ + char *p; + int n, nsig; + Fmt fmt; + uchar digest[SHA1dlen], sig[1024]; + char *text; + Attr *a; + DSAsig dsig; + DSApub dkey; + + a = _parseattr(key); + if(a == nil) + sysfatal("invalid key"); + dkey.alpha = keytomp(a, "alpha"); + dkey.key = keytomp(a, "key"); + dkey.p = keytomp(a, "p"); + dkey.q = keytomp(a, "q"); + if(!probably_prime(dkey.p, 20) && !probably_prime(dkey.q, 20)) + sysfatal("p or q not prime"); + + while((p = getline(&n)) != nil) + if(p[0] == '+' && strcmp(p+1, id) == 0) + goto start; + sysfatal("no message found"); + +start: + fmtstrinit(&fmt); + while((p = getline(&n)) != nil) { + if(n >= 1+nid+1+16 && p[0] == '-' && strncmp(p+1, id, nid) == 0 && p[1+nid] == ' ') { + if((nsig = dec16(sig, sizeof sig, p+1+nid+1, n-(1+nid+1))) != 20+20) + sysfatal("malformed signture"); + goto end; + } + if(p[0] == '+') + p++; + fmtprint(&fmt, "%s\n", p); + } + sysfatal("did not find end of message"); + +end: + text = fmtstrflush(&fmt); + sha1((uchar*)text, strlen(text), digest, nil); + + if(nsig != 40) + sysfatal("malformed signature"); + dsig.r = betomp(sig, 20, nil); + dsig.s = betomp(sig+20, 20, nil); + + if(dsaverify(&dkey, &dsig, betomp(digest, sizeof digest, nil)) < 0) + sysfatal("signature failed to verify: %r"); + + write(1, text, strlen(text)); + threadexitsall(0); +} + +char* +getline(int *np) +{ + char *p; + int n; + + if((p = Brdline(&b, '\n')) == nil) + return nil; + n = Blinelen(&b); + while(n > 0 && (p[n-1] == '\n' || p[n-1] == ' ' || p[n-1] == '\t')) + n--; + p[n] = '\0'; + *np = n; + return p; +} -- cgit v1.2.3