rsa.c 3.4 KB

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