📄 sshrsa.c
字号:
/* * 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 intsshrsainit(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 intsshrsaread(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(findkey(&s->key, fss, fss->sysuser, 1, s->off, fss->attr, nil) != RpcOk) 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 intsshrsawrite(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"); switch(canusekey(fss, s->key)){ case -1: return RpcConfirm; case 0: return failure(fss, "confirmation denied"); case 1: break; } m = strtomp(va, nil, 16, nil); m = rsadecrypt(s->key->priv, m, m); s->resp = m; fss->phase = CHaveResp; return RpcOk; }}static voidsshrsaclose(Fsstate *fss){ State *s; s = fss->ps; if(s->key) closekey(s->key); if(s->resp) mpfree(s->resp); free(s);}static intsshrsaaddkey(Key *k, int before){ fmtinstall('B', mpfmt); if((k->priv = readrsapriv(k)) == nil){ werrstr("malformed key data"); return -1; } return replacekey(k, before);}static voidsshrsaclosekey(Key *k){ rsaprivfree(k->priv);}Proto sshrsa = {.name= "sshrsa",.init= sshrsainit,.write= sshrsawrite,.read= sshrsaread,.close= sshrsaclose,.addkey= sshrsaaddkey,.closekey= sshrsaclosekey,};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -