rsa.c 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412
  1. /*
  2. * This file is part of the UCB release of Plan 9. It is subject to the license
  3. * terms in the LICENSE file found in the top-level directory of this
  4. * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
  5. * part of the UCB release of Plan 9, including this file, may be copied,
  6. * modified, propagated, or distributed except according to the terms contained
  7. * in the LICENSE file.
  8. */
  9. /*
  10. * RSA authentication.
  11. *
  12. * Old ssh client protocol:
  13. * read public key
  14. * if you don't like it, read another, repeat
  15. * write challenge
  16. * read response
  17. *
  18. * all numbers are hexadecimal biginits parsable with strtomp.
  19. *
  20. * Sign (PKCS #1 using hash=sha1 or hash=md5)
  21. * write hash(msg)
  22. * read signature(hash(msg))
  23. *
  24. * Verify:
  25. * write hash(msg)
  26. * write signature(hash(msg))
  27. * read ok or fail
  28. */
  29. #include "dat.h"
  30. enum {
  31. CHavePub,
  32. CHaveResp,
  33. VNeedHash,
  34. VNeedSig,
  35. VHaveResp,
  36. SNeedHash,
  37. SHaveResp,
  38. Maxphase,
  39. };
  40. static char *phasenames[] = {
  41. [CHavePub] "CHavePub",
  42. [CHaveResp] "CHaveResp",
  43. [VNeedHash] "VNeedHash",
  44. [VNeedSig] "VNeedSig",
  45. [VHaveResp] "VHaveResp",
  46. [SNeedHash] "SNeedHash",
  47. [SHaveResp] "SHaveResp",
  48. };
  49. struct State
  50. {
  51. RSApriv *priv;
  52. mpint *resp;
  53. int off;
  54. Key *key;
  55. mpint *digest;
  56. int sigresp;
  57. };
  58. static mpint* mkdigest(RSApub *key, char *hashalg, uint8_t *hash,
  59. uint dlen);
  60. static RSApriv*
  61. readrsapriv(Key *k)
  62. {
  63. char *a;
  64. RSApriv *priv;
  65. priv = rsaprivalloc();
  66. if((a=_strfindattr(k->attr, "ek"))==nil || (priv->pub.ek=strtomp(a, nil, 16, nil))==nil)
  67. goto Error;
  68. if((a=_strfindattr(k->attr, "n"))==nil || (priv->pub.n=strtomp(a, nil, 16, nil))==nil)
  69. goto Error;
  70. if(k->privattr == nil) /* only public half */
  71. return priv;
  72. if((a=_strfindattr(k->privattr, "!p"))==nil || (priv->p=strtomp(a, nil, 16, nil))==nil)
  73. goto Error;
  74. if((a=_strfindattr(k->privattr, "!q"))==nil || (priv->q=strtomp(a, nil, 16, nil))==nil)
  75. goto Error;
  76. if((a=_strfindattr(k->privattr, "!kp"))==nil || (priv->kp=strtomp(a, nil, 16, nil))==nil)
  77. goto Error;
  78. if((a=_strfindattr(k->privattr, "!kq"))==nil || (priv->kq=strtomp(a, nil, 16, nil))==nil)
  79. goto Error;
  80. if((a=_strfindattr(k->privattr, "!c2"))==nil || (priv->c2=strtomp(a, nil, 16, nil))==nil)
  81. goto Error;
  82. if((a=_strfindattr(k->privattr, "!dk"))==nil || (priv->dk=strtomp(a, nil, 16, nil))==nil)
  83. goto Error;
  84. return priv;
  85. Error:
  86. rsaprivfree(priv);
  87. return nil;
  88. }
  89. static int
  90. rsainit(Proto* p, Fsstate *fss)
  91. {
  92. Keyinfo ki;
  93. State *s;
  94. char *role;
  95. if((role = _strfindattr(fss->attr, "role")) == nil)
  96. return failure(fss, "rsa role not specified");
  97. if(strcmp(role, "client") == 0)
  98. fss->phase = CHavePub;
  99. else if(strcmp(role, "sign") == 0)
  100. fss->phase = SNeedHash;
  101. else if(strcmp(role, "verify") == 0)
  102. fss->phase = VNeedHash;
  103. else
  104. return failure(fss, "rsa role %s unimplemented", role);
  105. s = emalloc(sizeof *s);
  106. fss->phasename = phasenames;
  107. fss->maxphase = Maxphase;
  108. fss->ps = s;
  109. switch(fss->phase){
  110. case SNeedHash:
  111. case VNeedHash:
  112. mkkeyinfo(&ki, fss, nil);
  113. if(findkey(&s->key, &ki, nil) != RpcOk)
  114. return failure(fss, nil);
  115. /* signing needs private key */
  116. if(fss->phase == SNeedHash && s->key->privattr == nil)
  117. return failure(fss,
  118. "missing private half of key -- cannot sign");
  119. }
  120. return RpcOk;
  121. }
  122. static int
  123. rsaread(Fsstate *fss, void *va, uint *n)
  124. {
  125. RSApriv *priv;
  126. State *s;
  127. mpint *m;
  128. Keyinfo ki;
  129. int len, r;
  130. s = fss->ps;
  131. switch(fss->phase){
  132. default:
  133. return phaseerror(fss, "read");
  134. case CHavePub:
  135. if(s->key){
  136. closekey(s->key);
  137. s->key = nil;
  138. }
  139. mkkeyinfo(&ki, fss, nil);
  140. ki.skip = s->off;
  141. ki.noconf = 1;
  142. if(findkey(&s->key, &ki, nil) != RpcOk)
  143. return failure(fss, nil);
  144. s->off++;
  145. priv = s->key->priv;
  146. *n = snprint(va, *n, "%B", priv->pub.n);
  147. return RpcOk;
  148. case CHaveResp:
  149. *n = snprint(va, *n, "%B", s->resp);
  150. fss->phase = Established;
  151. return RpcOk;
  152. case SHaveResp:
  153. priv = s->key->priv;
  154. len = (mpsignif(priv->pub.n)+7)/8;
  155. if(len > *n)
  156. return failure(fss, "signature buffer too short");
  157. m = rsadecrypt(priv, s->digest, nil);
  158. r = mptobe(m, (uint8_t*)va, len, nil);
  159. if(r < len){
  160. memmove((uint8_t*)va+len-r, va, r);
  161. memset(va, 0, len-r);
  162. }
  163. *n = len;
  164. mpfree(m);
  165. fss->phase = Established;
  166. return RpcOk;
  167. case VHaveResp:
  168. *n = snprint(va, *n, "%s", s->sigresp == 0? "ok":
  169. "signature does not verify");
  170. fss->phase = Established;
  171. return RpcOk;
  172. }
  173. }
  174. static int
  175. rsawrite(Fsstate *fss, void *va, uint n)
  176. {
  177. RSApriv *priv;
  178. mpint *m, *mm;
  179. State *s;
  180. char *hash;
  181. int dlen;
  182. s = fss->ps;
  183. switch(fss->phase){
  184. default:
  185. return phaseerror(fss, "write");
  186. case CHavePub:
  187. if(s->key == nil)
  188. return failure(fss, "no current key");
  189. switch(canusekey(fss, s->key)){
  190. case -1:
  191. return RpcConfirm;
  192. case 0:
  193. return failure(fss, "confirmation denied");
  194. case 1:
  195. break;
  196. }
  197. m = strtomp(va, nil, 16, nil);
  198. if(m == nil)
  199. return failure(fss, "invalid challenge value");
  200. m = rsadecrypt(s->key->priv, m, m);
  201. s->resp = m;
  202. fss->phase = CHaveResp;
  203. return RpcOk;
  204. case SNeedHash:
  205. case VNeedHash:
  206. /* get hash type from key */
  207. hash = _strfindattr(s->key->attr, "hash");
  208. if(hash == nil)
  209. hash = "sha1";
  210. if(strcmp(hash, "sha1") == 0)
  211. dlen = SHA1dlen;
  212. else if(strcmp(hash, "md5") == 0)
  213. dlen = MD5dlen;
  214. else
  215. return failure(fss, "unknown hash function %s", hash);
  216. if(n != dlen)
  217. return failure(fss, "hash length %d should be %d",
  218. n, dlen);
  219. priv = s->key->priv;
  220. s->digest = mkdigest(&priv->pub, hash, (uint8_t *)va, n);
  221. if(s->digest == nil)
  222. return failure(fss, nil);
  223. if(fss->phase == VNeedHash)
  224. fss->phase = VNeedSig;
  225. else
  226. fss->phase = SHaveResp;
  227. return RpcOk;
  228. case VNeedSig:
  229. priv = s->key->priv;
  230. m = betomp((uint8_t*)va, n, nil);
  231. mm = rsaencrypt(&priv->pub, m, nil);
  232. s->sigresp = mpcmp(s->digest, mm);
  233. mpfree(m);
  234. mpfree(mm);
  235. fss->phase = VHaveResp;
  236. return RpcOk;
  237. }
  238. }
  239. static void
  240. rsaclose(Fsstate *fss)
  241. {
  242. State *s;
  243. s = fss->ps;
  244. if(s->key)
  245. closekey(s->key);
  246. if(s->resp)
  247. mpfree(s->resp);
  248. if(s->digest)
  249. mpfree(s->digest);
  250. free(s);
  251. }
  252. static int
  253. rsaaddkey(Key *k, int before)
  254. {
  255. fmtinstall('B', mpfmt);
  256. if((k->priv = readrsapriv(k)) == nil){
  257. werrstr("malformed key data");
  258. return -1;
  259. }
  260. return replacekey(k, before);
  261. }
  262. static void
  263. rsaclosekey(Key *k)
  264. {
  265. rsaprivfree(k->priv);
  266. }
  267. Proto rsa = {
  268. .name= "rsa",
  269. .init= rsainit,
  270. .write= rsawrite,
  271. .read= rsaread,
  272. .close= rsaclose,
  273. .addkey= rsaaddkey,
  274. .closekey= rsaclosekey,
  275. };
  276. /*
  277. * Simple ASN.1 encodings.
  278. * Lengths < 128 are encoded as 1-bytes constants,
  279. * making our life easy.
  280. */
  281. /*
  282. * Hash OIDs
  283. *
  284. * SHA1 = 1.3.14.3.2.26
  285. * MDx = 1.2.840.113549.2.x
  286. */
  287. #define O0(a,b) ((a)*40+(b))
  288. #define O2(x) \
  289. (((x)>> 7)&0x7F)|0x80, \
  290. ((x)&0x7F)
  291. #define O3(x) \
  292. (((x)>>14)&0x7F)|0x80, \
  293. (((x)>> 7)&0x7F)|0x80, \
  294. ((x)&0x7F)
  295. uint8_t oidsha1[] = { O0(1, 3), 14, 3, 2, 26 };
  296. uint8_t oidmd2[] = { O0(1, 2), O2(840), O3(113549), 2, 2 };
  297. uint8_t oidmd5[] = { O0(1, 2), O2(840), O3(113549), 2, 5 };
  298. /*
  299. * DigestInfo ::= SEQUENCE {
  300. * digestAlgorithm AlgorithmIdentifier,
  301. * digest OCTET STRING
  302. * }
  303. *
  304. * except that OpenSSL seems to sign
  305. *
  306. * DigestInfo ::= SEQUENCE {
  307. * SEQUENCE{ digestAlgorithm AlgorithmIdentifier, NULL }
  308. * digest OCTET STRING
  309. * }
  310. *
  311. * instead. Sigh.
  312. */
  313. static int
  314. mkasn1(uint8_t *asn1, char *alg, uint8_t *d, uint dlen)
  315. {
  316. uint8_t *obj, *p;
  317. uint olen;
  318. if(strcmp(alg, "sha1") == 0){
  319. obj = oidsha1;
  320. olen = sizeof(oidsha1);
  321. }else if(strcmp(alg, "md5") == 0){
  322. obj = oidmd5;
  323. olen = sizeof(oidmd5);
  324. }else{
  325. sysfatal("bad alg in mkasn1");
  326. return -1;
  327. }
  328. p = asn1;
  329. *p++ = 0x30; /* sequence */
  330. p++;
  331. *p++ = 0x30; /* another sequence */
  332. p++;
  333. *p++ = 0x06; /* object id */
  334. *p++ = olen;
  335. memmove(p, obj, olen);
  336. p += olen;
  337. *p++ = 0x05; /* null */
  338. *p++ = 0;
  339. asn1[3] = p - (asn1+4); /* end of inner sequence */
  340. *p++ = 0x04; /* octet string */
  341. *p++ = dlen;
  342. memmove(p, d, dlen);
  343. p += dlen;
  344. asn1[1] = p - (asn1+2); /* end of outer sequence */
  345. return p - asn1;
  346. }
  347. static mpint*
  348. mkdigest(RSApub *key, char *hashalg, uint8_t *hash, uint dlen)
  349. {
  350. mpint *m;
  351. uint8_t asn1[512], *buf;
  352. int len, n, pad;
  353. /*
  354. * Create ASN.1
  355. */
  356. n = mkasn1(asn1, hashalg, hash, dlen);
  357. /*
  358. * PKCS#1 padding
  359. */
  360. len = (mpsignif(key->n)+7)/8 - 1;
  361. if(len < n+2){
  362. werrstr("rsa key too short");
  363. return nil;
  364. }
  365. pad = len - (n+2);
  366. buf = emalloc(len);
  367. buf[0] = 0x01;
  368. memset(buf+1, 0xFF, pad);
  369. buf[1+pad] = 0x00;
  370. memmove(buf+1+pad+1, asn1, n);
  371. m = betomp(buf, len, nil);
  372. free(buf);
  373. return m;
  374. }