Small tweaks
Lots of new code imported.
This commit is contained in:
parent
a770daa795
commit
2277c5d7bb
86 changed files with 12444 additions and 91 deletions
172
src/cmd/factotum/sshrsa.c
Normal file
172
src/cmd/factotum/sshrsa.c
Normal file
|
|
@ -0,0 +1,172 @@
|
|||
/*
|
||||
* SSH RSA authentication.
|
||||
*
|
||||
* Client protocol:
|
||||
* read public key
|
||||
* if you don't like it, read another, repeat
|
||||
* write challenge
|
||||
* read response
|
||||
* all numbers are hexadecimal biginits parsable with strtomp.
|
||||
*/
|
||||
|
||||
#include "dat.h"
|
||||
|
||||
enum {
|
||||
CHavePub,
|
||||
CHaveResp,
|
||||
|
||||
Maxphase,
|
||||
};
|
||||
|
||||
static char *phasenames[] = {
|
||||
[CHavePub] "CHavePub",
|
||||
[CHaveResp] "CHaveResp",
|
||||
};
|
||||
|
||||
struct State
|
||||
{
|
||||
RSApriv *priv;
|
||||
mpint *resp;
|
||||
int off;
|
||||
Key *key;
|
||||
};
|
||||
|
||||
static RSApriv*
|
||||
readrsapriv(Key *k)
|
||||
{
|
||||
char *a;
|
||||
RSApriv *priv;
|
||||
|
||||
priv = rsaprivalloc();
|
||||
|
||||
if((a=strfindattr(k->attr, "ek"))==nil || (priv->pub.ek=strtomp(a, nil, 16, nil))==nil)
|
||||
goto Error;
|
||||
if((a=strfindattr(k->attr, "n"))==nil || (priv->pub.n=strtomp(a, nil, 16, nil))==nil)
|
||||
goto Error;
|
||||
if((a=strfindattr(k->privattr, "!p"))==nil || (priv->p=strtomp(a, nil, 16, nil))==nil)
|
||||
goto Error;
|
||||
if((a=strfindattr(k->privattr, "!q"))==nil || (priv->q=strtomp(a, nil, 16, nil))==nil)
|
||||
goto Error;
|
||||
if((a=strfindattr(k->privattr, "!kp"))==nil || (priv->kp=strtomp(a, nil, 16, nil))==nil)
|
||||
goto Error;
|
||||
if((a=strfindattr(k->privattr, "!kq"))==nil || (priv->kq=strtomp(a, nil, 16, nil))==nil)
|
||||
goto Error;
|
||||
if((a=strfindattr(k->privattr, "!c2"))==nil || (priv->c2=strtomp(a, nil, 16, nil))==nil)
|
||||
goto Error;
|
||||
if((a=strfindattr(k->privattr, "!dk"))==nil || (priv->dk=strtomp(a, nil, 16, nil))==nil)
|
||||
goto Error;
|
||||
return priv;
|
||||
|
||||
Error:
|
||||
rsaprivfree(priv);
|
||||
return nil;
|
||||
}
|
||||
|
||||
static int
|
||||
sshrsainit(Proto*, Fsstate *fss)
|
||||
{
|
||||
int iscli;
|
||||
State *s;
|
||||
|
||||
if((iscli = isclient(strfindattr(fss->attr, "role"))) < 0)
|
||||
return failure(fss, nil);
|
||||
if(iscli==0)
|
||||
return failure(fss, "sshrsa server unimplemented");
|
||||
|
||||
s = emalloc(sizeof *s);
|
||||
fss->phasename = phasenames;
|
||||
fss->maxphase = Maxphase;
|
||||
fss->phase = CHavePub;
|
||||
fss->ps = s;
|
||||
return RpcOk;
|
||||
}
|
||||
|
||||
static int
|
||||
sshrsaread(Fsstate *fss, void *va, uint *n)
|
||||
{
|
||||
RSApriv *priv;
|
||||
State *s;
|
||||
|
||||
s = fss->ps;
|
||||
switch(fss->phase){
|
||||
default:
|
||||
return phaseerror(fss, "read");
|
||||
case CHavePub:
|
||||
if(s->key){
|
||||
closekey(s->key);
|
||||
s->key = nil;
|
||||
}
|
||||
if((s->key = findkey(fss, Kuser, nil, s->off, fss->attr, nil)) == nil)
|
||||
return failure(fss, nil);
|
||||
s->off++;
|
||||
priv = s->key->priv;
|
||||
*n = snprint(va, *n, "%B", priv->pub.n);
|
||||
return RpcOk;
|
||||
case CHaveResp:
|
||||
*n = snprint(va, *n, "%B", s->resp);
|
||||
fss->phase = Established;
|
||||
return RpcOk;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
sshrsawrite(Fsstate *fss, void *va, uint)
|
||||
{
|
||||
mpint *m;
|
||||
State *s;
|
||||
|
||||
s = fss->ps;
|
||||
switch(fss->phase){
|
||||
default:
|
||||
return phaseerror(fss, "write");
|
||||
case CHavePub:
|
||||
if(s->key == nil)
|
||||
return failure(fss, "no current key");
|
||||
m = strtomp(va, nil, 16, nil);
|
||||
m = rsadecrypt(s->key->priv, m, m);
|
||||
s->resp = m;
|
||||
fss->phase = CHaveResp;
|
||||
return RpcOk;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
sshrsaclose(Fsstate *fss)
|
||||
{
|
||||
State *s;
|
||||
|
||||
s = fss->ps;
|
||||
if(s->key)
|
||||
closekey(s->key);
|
||||
if(s->resp)
|
||||
mpfree(s->resp);
|
||||
free(s);
|
||||
}
|
||||
|
||||
static int
|
||||
sshrsaaddkey(Key *k)
|
||||
{
|
||||
fmtinstall('B', mpconv);
|
||||
|
||||
if((k->priv = readrsapriv(k)) == nil){
|
||||
werrstr("malformed key data");
|
||||
return -1;
|
||||
}
|
||||
return replacekey(k);
|
||||
}
|
||||
|
||||
static void
|
||||
sshrsaclosekey(Key *k)
|
||||
{
|
||||
rsaprivfree(k->priv);
|
||||
}
|
||||
|
||||
Proto sshrsa = {
|
||||
.name= "sshrsa",
|
||||
.init= sshrsainit,
|
||||
.write= sshrsawrite,
|
||||
.read= sshrsaread,
|
||||
.close= sshrsaclose,
|
||||
.addkey= sshrsaaddkey,
|
||||
.closekey= sshrsaclosekey,
|
||||
};
|
||||
Loading…
Add table
Add a link
Reference in a new issue