1 #include "std.h"
2 #include "dat.h"
3
4 /*
5 * DSA signing and verification
6 *
7 * Sign:
8 * start p=xxx q=xxx alpha=xxx key=xxx
9 * write msg
10 * read signature(msg)
11 *
12 * Verify: (not implemented)
13 * start p=xxx q=xxx alpha=xxx key=xxx
14 * write msg
15 * write signature(msg)
16 * read ok or fail
17 *
18 * all numbers are hexadecimal bigints parsable with strtomp.
19 */
20
21 static int
xdsasign(Conv * c)22 xdsasign(Conv *c)
23 {
24 int n;
25 mpint *m;
26 uchar digest[SHA1dlen], sigblob[20+20];
27 DSAsig *sig;
28 Key *k;
29
30 k = keylookup("%A", c->attr);
31 if(k == nil)
32 return -1;
33
34 c->state = "read data";
35 if((n=convread(c, digest, SHA1dlen)) < 0){
36 keyclose(k);
37 return -1;
38 }
39 m = betomp(digest, SHA1dlen, nil);
40 if(m == nil){
41 keyclose(k);
42 return -1;
43 }
44 sig = dsasign(k->priv, m);
45 keyclose(k);
46 mpfree(m);
47 if(sig == nil)
48 return -1;
49 if(mpsignif(sig->r) > 20*8 || mpsignif(sig->s) > 20*8){
50 werrstr("signature too long");
51 return -1;
52 }
53 mptoberjust(sig->r, sigblob, 20);
54 mptoberjust(sig->s, sigblob+20, 20);
55 convwrite(c, sigblob, sizeof sigblob);
56 dsasigfree(sig);
57 return 0;
58 }
59
60 /*
61 * convert to canonical form (lower case)
62 * for use in attribute matches.
63 */
64 static void
strlwr(char * a)65 strlwr(char *a)
66 {
67 for(; *a; a++){
68 if('A' <= *a && *a <= 'Z')
69 *a += 'a' - 'A';
70 }
71 }
72
73 static DSApriv*
readdsapriv(Key * k)74 readdsapriv(Key *k)
75 {
76 char *a;
77 DSApriv *priv;
78
79 priv = dsaprivalloc();
80
81 if((a=strfindattr(k->attr, "p"))==nil
82 || (priv->pub.p=strtomp(a, nil, 16, nil))==nil)
83 goto Error;
84 strlwr(a);
85 if((a=strfindattr(k->attr, "q"))==nil
86 || (priv->pub.q=strtomp(a, nil, 16, nil))==nil)
87 goto Error;
88 strlwr(a);
89 if(!probably_prime(priv->pub.p, 20) && !probably_prime(priv->pub.q, 20)) {
90 werrstr("dsa: p or q not prime");
91 goto Error;
92 }
93 if((a=strfindattr(k->attr, "alpha"))==nil
94 || (priv->pub.alpha=strtomp(a, nil, 16, nil))==nil)
95 goto Error;
96 strlwr(a);
97 if((a=strfindattr(k->attr, "key"))==nil
98 || (priv->pub.key=strtomp(a, nil, 16, nil))==nil)
99 goto Error;
100 strlwr(a);
101 if((a=strfindattr(k->privattr, "!secret"))==nil
102 || (priv->secret=strtomp(a, nil, 16, nil))==nil)
103 goto Error;
104 strlwr(a);
105 return priv;
106
107 Error:
108 dsaprivfree(priv);
109 return nil;
110 }
111
112 static int
dsacheck(Key * k)113 dsacheck(Key *k)
114 {
115 static int first = 1;
116
117 if(first){
118 fmtinstall('B', mpfmt);
119 first = 0;
120 }
121
122 if((k->priv = readdsapriv(k)) == nil){
123 werrstr("malformed key data");
124 return -1;
125 }
126 return 0;
127 }
128
129 static void
dsaclose(Key * k)130 dsaclose(Key *k)
131 {
132 dsaprivfree(k->priv);
133 k->priv = nil;
134 }
135
136 static Role
137 dsaroles[] =
138 {
139 "sign", xdsasign,
140 0
141 };
142
143 Proto dsa = {
144 "dsa",
145 dsaroles,
146 nil,
147 dsacheck,
148 dsaclose
149 };
150