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 State
13 {
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 int
53 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 int
72 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 int
90 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;
110 agentlog("ssh use");
111 m = rsadecrypt(s->priv, m, m);
112 s->resp = m;
113 s->phase = Readresp;
114 return n;
117 void
118 sshrsaclose(void *v)
120 Sshrsastate *s;
122 s = v;
123 rsaprivfree(s->priv);
124 mpfree(s->resp);
125 free(s);
128 Proto sshrsa = {
129 .name= "ssh-rsa",
130 .perm= 0666,
131 .open= sshrsaopen,
132 .read= sshrsaread,
133 .write= sshrsawrite,
134 .close= sshrsaclose,
135 };