Blame


1 0e43f5c6 2011-10-05 rsc #include <u.h>
2 0e43f5c6 2011-10-05 rsc #include <libc.h>
3 0e43f5c6 2011-10-05 rsc #include <mp.h>
4 0e43f5c6 2011-10-05 rsc #include <libsec.h>
5 0e43f5c6 2011-10-05 rsc #include <auth.h>
6 0e43f5c6 2011-10-05 rsc #include <thread.h>
7 0e43f5c6 2011-10-05 rsc #include <9pclient.h>
8 0e43f5c6 2011-10-05 rsc #include <bio.h>
9 0e43f5c6 2011-10-05 rsc
10 0e43f5c6 2011-10-05 rsc void
11 0e43f5c6 2011-10-05 rsc usage(void)
12 0e43f5c6 2011-10-05 rsc {
13 0e43f5c6 2011-10-05 rsc fprint(2, "usage: 9 dsasign [-i id] [-v] key <data\n");
14 0e43f5c6 2011-10-05 rsc threadexitsall("usage");
15 0e43f5c6 2011-10-05 rsc }
16 0e43f5c6 2011-10-05 rsc
17 0e43f5c6 2011-10-05 rsc static void doVerify(void);
18 0e43f5c6 2011-10-05 rsc static char *getline(int*);
19 0e43f5c6 2011-10-05 rsc
20 0e43f5c6 2011-10-05 rsc char *id;
21 0e43f5c6 2011-10-05 rsc Biobuf b;
22 0e43f5c6 2011-10-05 rsc int nid;
23 0e43f5c6 2011-10-05 rsc char *key;
24 0e43f5c6 2011-10-05 rsc
25 0e43f5c6 2011-10-05 rsc void
26 0e43f5c6 2011-10-05 rsc threadmain(int argc, char **argv)
27 0e43f5c6 2011-10-05 rsc {
28 0e43f5c6 2011-10-05 rsc int n, verify;
29 0e43f5c6 2011-10-05 rsc char *text, *p;
30 0e43f5c6 2011-10-05 rsc uchar digest[SHA1dlen];
31 0e43f5c6 2011-10-05 rsc AuthRpc *rpc;
32 0e43f5c6 2011-10-05 rsc Fmt fmt;
33 fa325e9b 2020-01-10 cross
34 0e43f5c6 2011-10-05 rsc fmtinstall('[', encodefmt);
35 0e43f5c6 2011-10-05 rsc fmtinstall('H', encodefmt);
36 fa325e9b 2020-01-10 cross
37 0e43f5c6 2011-10-05 rsc verify = 0;
38 0e43f5c6 2011-10-05 rsc id = "";
39 0e43f5c6 2011-10-05 rsc ARGBEGIN{
40 0e43f5c6 2011-10-05 rsc case 'i':
41 0e43f5c6 2011-10-05 rsc id = EARGF(usage());
42 0e43f5c6 2011-10-05 rsc break;
43 0e43f5c6 2011-10-05 rsc case 'v':
44 0e43f5c6 2011-10-05 rsc verify = 1;
45 0e43f5c6 2011-10-05 rsc break;
46 0e43f5c6 2011-10-05 rsc default:
47 0e43f5c6 2011-10-05 rsc usage();
48 0e43f5c6 2011-10-05 rsc }ARGEND
49 fa325e9b 2020-01-10 cross
50 0e43f5c6 2011-10-05 rsc if(argc != 1)
51 0e43f5c6 2011-10-05 rsc usage();
52 0e43f5c6 2011-10-05 rsc key = argv[0];
53 0e43f5c6 2011-10-05 rsc nid = strlen(id);
54 0e43f5c6 2011-10-05 rsc
55 0e43f5c6 2011-10-05 rsc Binit(&b, 0, OREAD);
56 0e43f5c6 2011-10-05 rsc if(verify) {
57 0e43f5c6 2011-10-05 rsc doVerify();
58 0e43f5c6 2011-10-05 rsc threadexitsall(nil);
59 0e43f5c6 2011-10-05 rsc }
60 0e43f5c6 2011-10-05 rsc
61 0e43f5c6 2011-10-05 rsc if((rpc = auth_allocrpc()) == nil){
62 0e43f5c6 2011-10-05 rsc fprint(2, "dsasign: auth_allocrpc: %r\n");
63 0e43f5c6 2011-10-05 rsc threadexits("rpc");
64 0e43f5c6 2011-10-05 rsc }
65 0e43f5c6 2011-10-05 rsc key = smprint("proto=dsa role=sign %s", key);
66 0e43f5c6 2011-10-05 rsc if(auth_rpc(rpc, "start", key, strlen(key)) != ARok){
67 0e43f5c6 2011-10-05 rsc fprint(2, "dsasign: auth 'start' failed: %r\n");
68 0e43f5c6 2011-10-05 rsc auth_freerpc(rpc);
69 0e43f5c6 2011-10-05 rsc threadexits("rpc");
70 0e43f5c6 2011-10-05 rsc }
71 fa325e9b 2020-01-10 cross
72 0e43f5c6 2011-10-05 rsc print("+%s\n", id);
73 0e43f5c6 2011-10-05 rsc
74 0e43f5c6 2011-10-05 rsc Binit(&b, 0, OREAD);
75 0e43f5c6 2011-10-05 rsc fmtstrinit(&fmt);
76 0e43f5c6 2011-10-05 rsc while((p = getline(&n)) != nil) {
77 0e43f5c6 2011-10-05 rsc if(p[0] == '-' || p[0] == '+')
78 0e43f5c6 2011-10-05 rsc print("+");
79 0e43f5c6 2011-10-05 rsc print("%s\n", p);
80 0e43f5c6 2011-10-05 rsc fmtprint(&fmt, "%s\n", p);
81 0e43f5c6 2011-10-05 rsc }
82 0e43f5c6 2011-10-05 rsc text = fmtstrflush(&fmt);
83 0e43f5c6 2011-10-05 rsc sha1((uchar*)text, strlen(text), digest, nil);
84 0e43f5c6 2011-10-05 rsc
85 0e43f5c6 2011-10-05 rsc if(auth_rpc(rpc, "write", digest, SHA1dlen) != ARok)
86 0e43f5c6 2011-10-05 rsc sysfatal("auth write in sign failed: %r");
87 0e43f5c6 2011-10-05 rsc if(auth_rpc(rpc, "read", nil, 0) != ARok)
88 0e43f5c6 2011-10-05 rsc sysfatal("auth read in sign failed: %r");
89 0e43f5c6 2011-10-05 rsc
90 0e43f5c6 2011-10-05 rsc print("-%s %.*H\n", id, rpc->narg, rpc->arg);
91 0e43f5c6 2011-10-05 rsc threadexits(nil);
92 0e43f5c6 2011-10-05 rsc }
93 0e43f5c6 2011-10-05 rsc
94 0e43f5c6 2011-10-05 rsc static mpint*
95 0e43f5c6 2011-10-05 rsc keytomp(Attr *a, char *name)
96 0e43f5c6 2011-10-05 rsc {
97 0e43f5c6 2011-10-05 rsc char *p;
98 0e43f5c6 2011-10-05 rsc mpint *m;
99 fa325e9b 2020-01-10 cross
100 0e43f5c6 2011-10-05 rsc p = _strfindattr(a, name);
101 0e43f5c6 2011-10-05 rsc if(p == nil)
102 0e43f5c6 2011-10-05 rsc sysfatal("missing key attribute %s", name);
103 0e43f5c6 2011-10-05 rsc m = strtomp(p, nil, 16, nil);
104 0e43f5c6 2011-10-05 rsc if(m == nil)
105 0e43f5c6 2011-10-05 rsc sysfatal("malformed key attribute %s=%s", name, p);
106 0e43f5c6 2011-10-05 rsc return m;
107 0e43f5c6 2011-10-05 rsc }
108 0e43f5c6 2011-10-05 rsc
109 0e43f5c6 2011-10-05 rsc static void
110 0e43f5c6 2011-10-05 rsc doVerify(void)
111 0e43f5c6 2011-10-05 rsc {
112 0e43f5c6 2011-10-05 rsc char *p;
113 0e43f5c6 2011-10-05 rsc int n, nsig;
114 0e43f5c6 2011-10-05 rsc Fmt fmt;
115 0e43f5c6 2011-10-05 rsc uchar digest[SHA1dlen], sig[1024];
116 0e43f5c6 2011-10-05 rsc char *text;
117 0e43f5c6 2011-10-05 rsc Attr *a;
118 0e43f5c6 2011-10-05 rsc DSAsig dsig;
119 0e43f5c6 2011-10-05 rsc DSApub dkey;
120 fa325e9b 2020-01-10 cross
121 0e43f5c6 2011-10-05 rsc a = _parseattr(key);
122 0e43f5c6 2011-10-05 rsc if(a == nil)
123 0e43f5c6 2011-10-05 rsc sysfatal("invalid key");
124 0e43f5c6 2011-10-05 rsc dkey.alpha = keytomp(a, "alpha");
125 0e43f5c6 2011-10-05 rsc dkey.key = keytomp(a, "key");
126 0e43f5c6 2011-10-05 rsc dkey.p = keytomp(a, "p");
127 0e43f5c6 2011-10-05 rsc dkey.q = keytomp(a, "q");
128 0e43f5c6 2011-10-05 rsc if(!probably_prime(dkey.p, 20) && !probably_prime(dkey.q, 20))
129 0e43f5c6 2011-10-05 rsc sysfatal("p or q not prime");
130 0e43f5c6 2011-10-05 rsc
131 0e43f5c6 2011-10-05 rsc while((p = getline(&n)) != nil)
132 0e43f5c6 2011-10-05 rsc if(p[0] == '+' && strcmp(p+1, id) == 0)
133 0e43f5c6 2011-10-05 rsc goto start;
134 0e43f5c6 2011-10-05 rsc sysfatal("no message found");
135 0e43f5c6 2011-10-05 rsc
136 0e43f5c6 2011-10-05 rsc start:
137 0e43f5c6 2011-10-05 rsc fmtstrinit(&fmt);
138 0e43f5c6 2011-10-05 rsc while((p = getline(&n)) != nil) {
139 0e43f5c6 2011-10-05 rsc if(n >= 1+nid+1+16 && p[0] == '-' && strncmp(p+1, id, nid) == 0 && p[1+nid] == ' ') {
140 0e43f5c6 2011-10-05 rsc if((nsig = dec16(sig, sizeof sig, p+1+nid+1, n-(1+nid+1))) != 20+20)
141 0e43f5c6 2011-10-05 rsc sysfatal("malformed signture");
142 0e43f5c6 2011-10-05 rsc goto end;
143 0e43f5c6 2011-10-05 rsc }
144 0e43f5c6 2011-10-05 rsc if(p[0] == '+')
145 0e43f5c6 2011-10-05 rsc p++;
146 0e43f5c6 2011-10-05 rsc fmtprint(&fmt, "%s\n", p);
147 0e43f5c6 2011-10-05 rsc }
148 0e43f5c6 2011-10-05 rsc sysfatal("did not find end of message");
149 0cfb3760 2012-10-21 rsc return; // silence clang warning
150 0e43f5c6 2011-10-05 rsc
151 0e43f5c6 2011-10-05 rsc end:
152 0e43f5c6 2011-10-05 rsc text = fmtstrflush(&fmt);
153 0e43f5c6 2011-10-05 rsc sha1((uchar*)text, strlen(text), digest, nil);
154 0e43f5c6 2011-10-05 rsc
155 0e43f5c6 2011-10-05 rsc if(nsig != 40)
156 0e43f5c6 2011-10-05 rsc sysfatal("malformed signature");
157 0e43f5c6 2011-10-05 rsc dsig.r = betomp(sig, 20, nil);
158 0e43f5c6 2011-10-05 rsc dsig.s = betomp(sig+20, 20, nil);
159 0e43f5c6 2011-10-05 rsc
160 0e43f5c6 2011-10-05 rsc if(dsaverify(&dkey, &dsig, betomp(digest, sizeof digest, nil)) < 0)
161 0e43f5c6 2011-10-05 rsc sysfatal("signature failed to verify: %r");
162 fa325e9b 2020-01-10 cross
163 0e43f5c6 2011-10-05 rsc write(1, text, strlen(text));
164 0e43f5c6 2011-10-05 rsc threadexitsall(0);
165 0e43f5c6 2011-10-05 rsc }
166 0e43f5c6 2011-10-05 rsc
167 0e43f5c6 2011-10-05 rsc char*
168 0e43f5c6 2011-10-05 rsc getline(int *np)
169 0e43f5c6 2011-10-05 rsc {
170 0e43f5c6 2011-10-05 rsc char *p;
171 0e43f5c6 2011-10-05 rsc int n;
172 fa325e9b 2020-01-10 cross
173 0e43f5c6 2011-10-05 rsc if((p = Brdline(&b, '\n')) == nil)
174 0e43f5c6 2011-10-05 rsc return nil;
175 0e43f5c6 2011-10-05 rsc n = Blinelen(&b);
176 0e43f5c6 2011-10-05 rsc while(n > 0 && (p[n-1] == '\n' || p[n-1] == ' ' || p[n-1] == '\t'))
177 0e43f5c6 2011-10-05 rsc n--;
178 0e43f5c6 2011-10-05 rsc p[n] = '\0';
179 0e43f5c6 2011-10-05 rsc *np = n;
180 0e43f5c6 2011-10-05 rsc return p;
181 0e43f5c6 2011-10-05 rsc }