URI:
       tdsa.c - plan9port - [fork] Plan 9 from user space
  HTML git clone git://src.adamsgaard.dk/plan9port
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
       tdsa.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 };