sshrsa.c 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. /*
  2. * SSH RSA authentication.
  3. *
  4. * Client protocol:
  5. * read public key
  6. * if you don't like it, read another, repeat
  7. * write challenge
  8. * read response
  9. * all numbers are hexadecimal biginits parsable with strtomp.
  10. */
  11. #include "dat.h"
  12. enum {
  13. CHavePub,
  14. CHaveResp,
  15. Maxphase,
  16. };
  17. static char *phasenames[] = {
  18. [CHavePub] "CHavePub",
  19. [CHaveResp] "CHaveResp",
  20. };
  21. struct State
  22. {
  23. RSApriv *priv;
  24. mpint *resp;
  25. int off;
  26. Key *key;
  27. };
  28. static RSApriv*
  29. readrsapriv(Key *k)
  30. {
  31. char *a;
  32. RSApriv *priv;
  33. priv = rsaprivalloc();
  34. if((a=_strfindattr(k->attr, "ek"))==nil || (priv->pub.ek=strtomp(a, nil, 16, nil))==nil)
  35. goto Error;
  36. if((a=_strfindattr(k->attr, "n"))==nil || (priv->pub.n=strtomp(a, nil, 16, nil))==nil)
  37. goto Error;
  38. if((a=_strfindattr(k->privattr, "!p"))==nil || (priv->p=strtomp(a, nil, 16, nil))==nil)
  39. goto Error;
  40. if((a=_strfindattr(k->privattr, "!q"))==nil || (priv->q=strtomp(a, nil, 16, nil))==nil)
  41. goto Error;
  42. if((a=_strfindattr(k->privattr, "!kp"))==nil || (priv->kp=strtomp(a, nil, 16, nil))==nil)
  43. goto Error;
  44. if((a=_strfindattr(k->privattr, "!kq"))==nil || (priv->kq=strtomp(a, nil, 16, nil))==nil)
  45. goto Error;
  46. if((a=_strfindattr(k->privattr, "!c2"))==nil || (priv->c2=strtomp(a, nil, 16, nil))==nil)
  47. goto Error;
  48. if((a=_strfindattr(k->privattr, "!dk"))==nil || (priv->dk=strtomp(a, nil, 16, nil))==nil)
  49. goto Error;
  50. return priv;
  51. Error:
  52. rsaprivfree(priv);
  53. return nil;
  54. }
  55. static int
  56. sshrsainit(Proto*, Fsstate *fss)
  57. {
  58. int iscli;
  59. State *s;
  60. if((iscli = isclient(_strfindattr(fss->attr, "role"))) < 0)
  61. return failure(fss, nil);
  62. if(iscli==0)
  63. return failure(fss, "sshrsa server unimplemented");
  64. s = emalloc(sizeof *s);
  65. fss->phasename = phasenames;
  66. fss->maxphase = Maxphase;
  67. fss->phase = CHavePub;
  68. fss->ps = s;
  69. return RpcOk;
  70. }
  71. static int
  72. sshrsaread(Fsstate *fss, void *va, uint *n)
  73. {
  74. RSApriv *priv;
  75. State *s;
  76. s = fss->ps;
  77. switch(fss->phase){
  78. default:
  79. return phaseerror(fss, "read");
  80. case CHavePub:
  81. if(s->key){
  82. closekey(s->key);
  83. s->key = nil;
  84. }
  85. if(findkey(&s->key, fss, fss->sysuser, 1, s->off, fss->attr, nil) != RpcOk)
  86. return failure(fss, nil);
  87. s->off++;
  88. priv = s->key->priv;
  89. *n = snprint(va, *n, "%B", priv->pub.n);
  90. return RpcOk;
  91. case CHaveResp:
  92. *n = snprint(va, *n, "%B", s->resp);
  93. fss->phase = Established;
  94. return RpcOk;
  95. }
  96. }
  97. static int
  98. sshrsawrite(Fsstate *fss, void *va, uint)
  99. {
  100. mpint *m;
  101. State *s;
  102. s = fss->ps;
  103. switch(fss->phase){
  104. default:
  105. return phaseerror(fss, "write");
  106. case CHavePub:
  107. if(s->key == nil)
  108. return failure(fss, "no current key");
  109. switch(canusekey(fss, s->key)){
  110. case -1:
  111. return RpcConfirm;
  112. case 0:
  113. return failure(fss, "confirmation denied");
  114. case 1:
  115. break;
  116. }
  117. m = strtomp(va, nil, 16, nil);
  118. m = rsadecrypt(s->key->priv, m, m);
  119. s->resp = m;
  120. fss->phase = CHaveResp;
  121. return RpcOk;
  122. }
  123. }
  124. static void
  125. sshrsaclose(Fsstate *fss)
  126. {
  127. State *s;
  128. s = fss->ps;
  129. if(s->key)
  130. closekey(s->key);
  131. if(s->resp)
  132. mpfree(s->resp);
  133. free(s);
  134. }
  135. static int
  136. sshrsaaddkey(Key *k, int before)
  137. {
  138. fmtinstall('B', mpfmt);
  139. if((k->priv = readrsapriv(k)) == nil){
  140. werrstr("malformed key data");
  141. return -1;
  142. }
  143. return replacekey(k, before);
  144. }
  145. static void
  146. sshrsaclosekey(Key *k)
  147. {
  148. rsaprivfree(k->priv);
  149. }
  150. Proto sshrsa = {
  151. .name= "sshrsa",
  152. .init= sshrsainit,
  153. .write= sshrsawrite,
  154. .read= sshrsaread,
  155. .close= sshrsaclose,
  156. .addkey= sshrsaaddkey,
  157. .closekey= sshrsaclosekey,
  158. };