plan9port

[fork] Plan 9 from user space
git clone git://src.adamsgaard.dk/plan9port # fast
git clone https://src.adamsgaard.dk/plan9port.git # slow
Log | Files | Refs | README | LICENSE Back to index

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 };