Blob
1 #include "dat.h"2 #include <mp.h>3 #include <libsec.h>5 typedef struct Sshrsastate Sshrsastate;7 enum {8 CReadpub,9 CWritechal,10 CReadresp,11 };12 struct State13 {14 RSApriv *priv;15 Key *k;16 mpint *resp;17 int phase;18 };20 static RSApriv*21 readrsapriv(char *s)22 {23 RSApriv *priv;25 priv = rsaprivalloc();27 strtoul(s, &s, 10);28 if((priv->pub.ek=strtomp(s, &s, 16, nil)) == nil)29 goto Error;30 if((priv->dk=strtomp(s, &s, 16, nil)) == nil)31 goto Error;32 if((priv->pub.n=strtomp(s, &s, 16, nil)) == nil)33 goto Error;34 if((priv->p=strtomp(s, &s, 16, nil)) == nil)35 goto Error;36 if((priv->q=strtomp(s, &s, 16, nil)) == nil)37 goto Error;38 if((priv->kp=strtomp(s, &s, 16, nil)) == nil)39 goto Error;40 if((priv->kq=strtomp(s, &s, 16, nil)) == nil)41 goto Error;42 if((priv->c2=strtomp(s, &s, 16, nil)) == nil)43 goto Error;45 return priv;47 Error:48 rsaprivfree(priv);49 return nil;50 }52 int53 sshinit(Fsstate *fss,54 sshrsaopen(Key *k, char*, int client)55 {56 Sshrsastate *s;58 fmtinstall('B', mpconv);59 assert(client);60 s = emalloc(sizeof *s);61 s->priv = readrsapriv(s_to_c(k->data));62 s->k = k;63 if(s->priv == nil){64 agentlog("error parsing ssh key %s", k->file);65 free(s);66 return nil;67 }68 return s;69 }71 int72 sshrsaread(void *va, void *buf, int n)73 {74 Sshrsastate *s;76 s = va;77 switch(s->phase){78 case Readpub:79 s->phase = Done;80 return snprint(buf, n, "%B", s->priv->pub.n);81 case Readresp:82 s->phase = Done;83 return snprint(buf, n, "%B", s->resp);84 default:85 return 0;86 }87 }89 int90 sshrsawrite(void *va, void *vbuf, int n)91 {92 mpint *m;93 char *buf;94 Sshrsastate *s;96 s = va;97 if((s->k->flags&Fconfirmuse) && confirm("ssh use") < 0)98 return -1;100 buf = emalloc(n+1);101 memmove(buf, vbuf, n);102 buf[n] = '\0';103 m = strtomp(buf, nil, 16, nil);104 free(buf);105 if(m == nil){106 werrstr("bad bignum");107 return -1;108 }110 agentlog("ssh use");111 m = rsadecrypt(s->priv, m, m);112 s->resp = m;113 s->phase = Readresp;114 return n;115 }117 void118 sshrsaclose(void *v)119 {120 Sshrsastate *s;122 s = v;123 rsaprivfree(s->priv);124 mpfree(s->resp);125 free(s);126 }128 Proto sshrsa = {129 .name= "ssh-rsa",130 .perm= 0666,131 .open= sshrsaopen,132 .read= sshrsaread,133 .write= sshrsawrite,134 .close= sshrsaclose,135 };