dsa.c (2499B)
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 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 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* 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 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 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 };