Blob


1 #include "std.h"
2 #include "dat.h"
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 */
21 static int
22 xdsasign(Conv *c)
23 {
24 int n;
25 mpint *m;
26 uchar digest[SHA1dlen], sigblob[20+20];
27 DSAsig *sig;
28 Key *k;
30 k = keylookup("%A", c->attr);
31 if(k == nil)
32 return -1;
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 }
60 /*
61 * convert to canonical form (lower case)
62 * for use in attribute matches.
63 */
64 static void
65 strlwr(char *a)
66 {
67 for(; *a; a++){
68 if('A' <= *a && *a <= 'Z')
69 *a += 'a' - 'A';
70 }
71 }
73 static DSApriv*
74 readdsapriv(Key *k)
75 {
76 char *a;
77 DSApriv *priv;
79 priv = dsaprivalloc();
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;
107 Error:
108 dsaprivfree(priv);
109 return nil;
112 static int
113 dsacheck(Key *k)
115 static int first = 1;
117 if(first){
118 fmtinstall('B', mpfmt);
119 first = 0;
122 if((k->priv = readdsapriv(k)) == nil){
123 werrstr("malformed key data");
124 return -1;
126 return 0;
129 static void
130 dsaclose(Key *k)
132 dsaprivfree(k->priv);
133 k->priv = nil;
136 static Role
137 dsaroles[] =
139 "sign", xdsasign,
141 };
143 Proto dsa = {
144 "dsa",
145 dsaroles,
146 nil,
147 dsacheck,
148 dsaclose
149 };