PageRenderTime 62ms CodeModel.GetById 31ms RepoModel.GetById 0ms app.codeStats 0ms

/openssh-5.3p1/scard.c

https://github.com/epriestley/sshd-vcs
C | 571 lines | 452 code | 81 blank | 38 comment | 88 complexity | 70f3e7422ceb7012a07c9b057f50c069 MD5 | raw file
  1. /* $OpenBSD: scard.c,v 1.36 2006/11/06 21:25:28 markus Exp $ */
  2. /*
  3. * Copyright (c) 2001 Markus Friedl. All rights reserved.
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that the following conditions
  7. * are met:
  8. * 1. Redistributions of source code must retain the above copyright
  9. * notice, this list of conditions and the following disclaimer.
  10. * 2. Redistributions in binary form must reproduce the above copyright
  11. * notice, this list of conditions and the following disclaimer in the
  12. * documentation and/or other materials provided with the distribution.
  13. *
  14. * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  15. * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  16. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  17. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  18. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  19. * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  20. * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  21. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  22. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  23. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  24. */
  25. #include "includes.h"
  26. #if defined(SMARTCARD) && defined(USE_SECTOK)
  27. #include <sys/types.h>
  28. #include <sectok.h>
  29. #include <stdarg.h>
  30. #include <string.h>
  31. #include <openssl/evp.h>
  32. #include "xmalloc.h"
  33. #include "key.h"
  34. #include "log.h"
  35. #include "misc.h"
  36. #include "scard.h"
  37. #if OPENSSL_VERSION_NUMBER < 0x00907000L
  38. #define USE_ENGINE
  39. #define RSA_get_default_method RSA_get_default_openssl_method
  40. #else
  41. #endif
  42. #ifdef USE_ENGINE
  43. #include <openssl/engine.h>
  44. #define sc_get_rsa sc_get_engine
  45. #else
  46. #define sc_get_rsa sc_get_rsa_method
  47. #endif
  48. #define CLA_SSH 0x05
  49. #define INS_DECRYPT 0x10
  50. #define INS_GET_KEYLENGTH 0x20
  51. #define INS_GET_PUBKEY 0x30
  52. #define INS_GET_RESPONSE 0xc0
  53. #define MAX_BUF_SIZE 256
  54. u_char DEFAUT0[] = {0xad, 0x9f, 0x61, 0xfe, 0xfa, 0x20, 0xce, 0x63};
  55. static int sc_fd = -1;
  56. static char *sc_reader_id = NULL;
  57. static char *sc_pin = NULL;
  58. static int cla = 0x00; /* class */
  59. static void sc_mk_digest(const char *pin, u_char *digest);
  60. static int get_AUT0(u_char *aut0);
  61. static int try_AUT0(void);
  62. /* interface to libsectok */
  63. static int
  64. sc_open(void)
  65. {
  66. int sw;
  67. if (sc_fd >= 0)
  68. return sc_fd;
  69. sc_fd = sectok_friendly_open(sc_reader_id, STONOWAIT, &sw);
  70. if (sc_fd < 0) {
  71. error("sectok_open failed: %s", sectok_get_sw(sw));
  72. return SCARD_ERROR_FAIL;
  73. }
  74. if (! sectok_cardpresent(sc_fd)) {
  75. debug("smartcard in reader %s not present, skipping",
  76. sc_reader_id);
  77. sc_close();
  78. return SCARD_ERROR_NOCARD;
  79. }
  80. if (sectok_reset(sc_fd, 0, NULL, &sw) <= 0) {
  81. error("sectok_reset failed: %s", sectok_get_sw(sw));
  82. sc_fd = -1;
  83. return SCARD_ERROR_FAIL;
  84. }
  85. if ((cla = cyberflex_inq_class(sc_fd)) < 0)
  86. cla = 0;
  87. debug("sc_open ok %d", sc_fd);
  88. return sc_fd;
  89. }
  90. static int
  91. sc_enable_applet(void)
  92. {
  93. static u_char aid[] = {0xfc, 0x53, 0x73, 0x68, 0x2e, 0x62, 0x69, 0x6e};
  94. int sw = 0;
  95. /* select applet id */
  96. sectok_apdu(sc_fd, cla, 0xa4, 0x04, 0, sizeof aid, aid, 0, NULL, &sw);
  97. if (!sectok_swOK(sw)) {
  98. error("sectok_apdu failed: %s", sectok_get_sw(sw));
  99. sc_close();
  100. return -1;
  101. }
  102. return 0;
  103. }
  104. static int
  105. sc_init(void)
  106. {
  107. int status;
  108. status = sc_open();
  109. if (status == SCARD_ERROR_NOCARD) {
  110. return SCARD_ERROR_NOCARD;
  111. }
  112. if (status < 0) {
  113. error("sc_open failed");
  114. return status;
  115. }
  116. if (sc_enable_applet() < 0) {
  117. error("sc_enable_applet failed");
  118. return SCARD_ERROR_APPLET;
  119. }
  120. return 0;
  121. }
  122. static int
  123. sc_read_pubkey(Key * k)
  124. {
  125. u_char buf[2], *n;
  126. char *p;
  127. int len, sw, status = -1;
  128. len = sw = 0;
  129. n = NULL;
  130. if (sc_fd < 0) {
  131. if (sc_init() < 0)
  132. goto err;
  133. }
  134. /* get key size */
  135. sectok_apdu(sc_fd, CLA_SSH, INS_GET_KEYLENGTH, 0, 0, 0, NULL,
  136. sizeof(buf), buf, &sw);
  137. if (!sectok_swOK(sw)) {
  138. error("could not obtain key length: %s", sectok_get_sw(sw));
  139. goto err;
  140. }
  141. len = (buf[0] << 8) | buf[1];
  142. len /= 8;
  143. debug("INS_GET_KEYLENGTH: len %d sw %s", len, sectok_get_sw(sw));
  144. n = xmalloc(len);
  145. /* get n */
  146. sectok_apdu(sc_fd, CLA_SSH, INS_GET_PUBKEY, 0, 0, 0, NULL, len, n, &sw);
  147. if (sw == 0x6982) {
  148. if (try_AUT0() < 0)
  149. goto err;
  150. sectok_apdu(sc_fd, CLA_SSH, INS_GET_PUBKEY, 0, 0, 0, NULL, len, n, &sw);
  151. }
  152. if (!sectok_swOK(sw)) {
  153. error("could not obtain public key: %s", sectok_get_sw(sw));
  154. goto err;
  155. }
  156. debug("INS_GET_KEYLENGTH: sw %s", sectok_get_sw(sw));
  157. if (BN_bin2bn(n, len, k->rsa->n) == NULL) {
  158. error("c_read_pubkey: BN_bin2bn failed");
  159. goto err;
  160. }
  161. /* currently the java applet just stores 'n' */
  162. if (!BN_set_word(k->rsa->e, 35)) {
  163. error("c_read_pubkey: BN_set_word(e, 35) failed");
  164. goto err;
  165. }
  166. status = 0;
  167. p = key_fingerprint(k, SSH_FP_MD5, SSH_FP_HEX);
  168. debug("fingerprint %u %s", key_size(k), p);
  169. xfree(p);
  170. err:
  171. if (n != NULL)
  172. xfree(n);
  173. sc_close();
  174. return status;
  175. }
  176. /* private key operations */
  177. static int
  178. sc_private_decrypt(int flen, u_char *from, u_char *to, RSA *rsa,
  179. int padding)
  180. {
  181. u_char *padded = NULL;
  182. int sw, len, olen, status = -1;
  183. debug("sc_private_decrypt called");
  184. olen = len = sw = 0;
  185. if (sc_fd < 0) {
  186. status = sc_init();
  187. if (status < 0)
  188. goto err;
  189. }
  190. if (padding != RSA_PKCS1_PADDING)
  191. goto err;
  192. len = BN_num_bytes(rsa->n);
  193. padded = xmalloc(len);
  194. sectok_apdu(sc_fd, CLA_SSH, INS_DECRYPT, 0, 0, len, from, len, padded, &sw);
  195. if (sw == 0x6982) {
  196. if (try_AUT0() < 0)
  197. goto err;
  198. sectok_apdu(sc_fd, CLA_SSH, INS_DECRYPT, 0, 0, len, from, len, padded, &sw);
  199. }
  200. if (!sectok_swOK(sw)) {
  201. error("sc_private_decrypt: INS_DECRYPT failed: %s",
  202. sectok_get_sw(sw));
  203. goto err;
  204. }
  205. olen = RSA_padding_check_PKCS1_type_2(to, len, padded + 1, len - 1,
  206. len);
  207. err:
  208. if (padded)
  209. xfree(padded);
  210. sc_close();
  211. return (olen >= 0 ? olen : status);
  212. }
  213. static int
  214. sc_private_encrypt(int flen, u_char *from, u_char *to, RSA *rsa,
  215. int padding)
  216. {
  217. u_char *padded = NULL;
  218. int sw, len, status = -1;
  219. len = sw = 0;
  220. if (sc_fd < 0) {
  221. status = sc_init();
  222. if (status < 0)
  223. goto err;
  224. }
  225. if (padding != RSA_PKCS1_PADDING)
  226. goto err;
  227. debug("sc_private_encrypt called");
  228. len = BN_num_bytes(rsa->n);
  229. padded = xmalloc(len);
  230. if (RSA_padding_add_PKCS1_type_1(padded, len, (u_char *)from, flen) <= 0) {
  231. error("RSA_padding_add_PKCS1_type_1 failed");
  232. goto err;
  233. }
  234. sectok_apdu(sc_fd, CLA_SSH, INS_DECRYPT, 0, 0, len, padded, len, to, &sw);
  235. if (sw == 0x6982) {
  236. if (try_AUT0() < 0)
  237. goto err;
  238. sectok_apdu(sc_fd, CLA_SSH, INS_DECRYPT, 0, 0, len, padded, len, to, &sw);
  239. }
  240. if (!sectok_swOK(sw)) {
  241. error("sc_private_encrypt: INS_DECRYPT failed: %s",
  242. sectok_get_sw(sw));
  243. goto err;
  244. }
  245. err:
  246. if (padded)
  247. xfree(padded);
  248. sc_close();
  249. return (len >= 0 ? len : status);
  250. }
  251. /* called on free */
  252. static int (*orig_finish)(RSA *rsa) = NULL;
  253. static int
  254. sc_finish(RSA *rsa)
  255. {
  256. if (orig_finish)
  257. orig_finish(rsa);
  258. sc_close();
  259. return 1;
  260. }
  261. /* engine for overloading private key operations */
  262. static RSA_METHOD *
  263. sc_get_rsa_method(void)
  264. {
  265. static RSA_METHOD smart_rsa;
  266. const RSA_METHOD *def = RSA_get_default_method();
  267. /* use the OpenSSL version */
  268. memcpy(&smart_rsa, def, sizeof(smart_rsa));
  269. smart_rsa.name = "sectok";
  270. /* overload */
  271. smart_rsa.rsa_priv_enc = sc_private_encrypt;
  272. smart_rsa.rsa_priv_dec = sc_private_decrypt;
  273. /* save original */
  274. orig_finish = def->finish;
  275. smart_rsa.finish = sc_finish;
  276. return &smart_rsa;
  277. }
  278. #ifdef USE_ENGINE
  279. static ENGINE *
  280. sc_get_engine(void)
  281. {
  282. static ENGINE *smart_engine = NULL;
  283. if ((smart_engine = ENGINE_new()) == NULL)
  284. fatal("ENGINE_new failed");
  285. ENGINE_set_id(smart_engine, "sectok");
  286. ENGINE_set_name(smart_engine, "libsectok");
  287. ENGINE_set_RSA(smart_engine, sc_get_rsa_method());
  288. ENGINE_set_DSA(smart_engine, DSA_get_default_openssl_method());
  289. ENGINE_set_DH(smart_engine, DH_get_default_openssl_method());
  290. ENGINE_set_RAND(smart_engine, RAND_SSLeay());
  291. ENGINE_set_BN_mod_exp(smart_engine, BN_mod_exp);
  292. return smart_engine;
  293. }
  294. #endif
  295. void
  296. sc_close(void)
  297. {
  298. if (sc_fd >= 0) {
  299. sectok_close(sc_fd);
  300. sc_fd = -1;
  301. }
  302. }
  303. Key **
  304. sc_get_keys(const char *id, const char *pin)
  305. {
  306. Key *k, *n, **keys;
  307. int status, nkeys = 2;
  308. if (sc_reader_id != NULL)
  309. xfree(sc_reader_id);
  310. sc_reader_id = xstrdup(id);
  311. if (sc_pin != NULL)
  312. xfree(sc_pin);
  313. sc_pin = (pin == NULL) ? NULL : xstrdup(pin);
  314. k = key_new(KEY_RSA);
  315. if (k == NULL) {
  316. return NULL;
  317. }
  318. status = sc_read_pubkey(k);
  319. if (status == SCARD_ERROR_NOCARD) {
  320. key_free(k);
  321. return NULL;
  322. }
  323. if (status < 0) {
  324. error("sc_read_pubkey failed");
  325. key_free(k);
  326. return NULL;
  327. }
  328. keys = xcalloc((nkeys+1), sizeof(Key *));
  329. n = key_new(KEY_RSA1);
  330. if ((BN_copy(n->rsa->n, k->rsa->n) == NULL) ||
  331. (BN_copy(n->rsa->e, k->rsa->e) == NULL))
  332. fatal("sc_get_keys: BN_copy failed");
  333. RSA_set_method(n->rsa, sc_get_rsa());
  334. n->flags |= KEY_FLAG_EXT;
  335. keys[0] = n;
  336. n = key_new(KEY_RSA);
  337. if ((BN_copy(n->rsa->n, k->rsa->n) == NULL) ||
  338. (BN_copy(n->rsa->e, k->rsa->e) == NULL))
  339. fatal("sc_get_keys: BN_copy failed");
  340. RSA_set_method(n->rsa, sc_get_rsa());
  341. n->flags |= KEY_FLAG_EXT;
  342. keys[1] = n;
  343. keys[2] = NULL;
  344. key_free(k);
  345. return keys;
  346. }
  347. #define NUM_RSA_KEY_ELEMENTS 5+1
  348. #define COPY_RSA_KEY(x, i) \
  349. do { \
  350. len = BN_num_bytes(prv->rsa->x); \
  351. elements[i] = xmalloc(len); \
  352. debug("#bytes %d", len); \
  353. if (BN_bn2bin(prv->rsa->x, elements[i]) < 0) \
  354. goto done; \
  355. } while (0)
  356. static void
  357. sc_mk_digest(const char *pin, u_char *digest)
  358. {
  359. const EVP_MD *evp_md = EVP_sha1();
  360. EVP_MD_CTX md;
  361. EVP_DigestInit(&md, evp_md);
  362. EVP_DigestUpdate(&md, pin, strlen(pin));
  363. EVP_DigestFinal(&md, digest, NULL);
  364. }
  365. static int
  366. get_AUT0(u_char *aut0)
  367. {
  368. char *pass;
  369. pass = read_passphrase("Enter passphrase for smartcard: ", RP_ALLOW_STDIN);
  370. if (pass == NULL)
  371. return -1;
  372. if (!strcmp(pass, "-")) {
  373. memcpy(aut0, DEFAUT0, sizeof DEFAUT0);
  374. return 0;
  375. }
  376. sc_mk_digest(pass, aut0);
  377. memset(pass, 0, strlen(pass));
  378. xfree(pass);
  379. return 0;
  380. }
  381. static int
  382. try_AUT0(void)
  383. {
  384. u_char aut0[EVP_MAX_MD_SIZE];
  385. /* permission denied; try PIN if provided */
  386. if (sc_pin && strlen(sc_pin) > 0) {
  387. sc_mk_digest(sc_pin, aut0);
  388. if (cyberflex_verify_AUT0(sc_fd, cla, aut0, 8) < 0) {
  389. error("smartcard passphrase incorrect");
  390. return (-1);
  391. }
  392. } else {
  393. /* try default AUT0 key */
  394. if (cyberflex_verify_AUT0(sc_fd, cla, DEFAUT0, 8) < 0) {
  395. /* default AUT0 key failed; prompt for passphrase */
  396. if (get_AUT0(aut0) < 0 ||
  397. cyberflex_verify_AUT0(sc_fd, cla, aut0, 8) < 0) {
  398. error("smartcard passphrase incorrect");
  399. return (-1);
  400. }
  401. }
  402. }
  403. return (0);
  404. }
  405. int
  406. sc_put_key(Key *prv, const char *id)
  407. {
  408. u_char *elements[NUM_RSA_KEY_ELEMENTS];
  409. u_char key_fid[2];
  410. u_char AUT0[EVP_MAX_MD_SIZE];
  411. int len, status = -1, i, fd = -1, ret;
  412. int sw = 0, cla = 0x00;
  413. for (i = 0; i < NUM_RSA_KEY_ELEMENTS; i++)
  414. elements[i] = NULL;
  415. COPY_RSA_KEY(q, 0);
  416. COPY_RSA_KEY(p, 1);
  417. COPY_RSA_KEY(iqmp, 2);
  418. COPY_RSA_KEY(dmq1, 3);
  419. COPY_RSA_KEY(dmp1, 4);
  420. COPY_RSA_KEY(n, 5);
  421. len = BN_num_bytes(prv->rsa->n);
  422. fd = sectok_friendly_open(id, STONOWAIT, &sw);
  423. if (fd < 0) {
  424. error("sectok_open failed: %s", sectok_get_sw(sw));
  425. goto done;
  426. }
  427. if (! sectok_cardpresent(fd)) {
  428. error("smartcard in reader %s not present", id);
  429. goto done;
  430. }
  431. ret = sectok_reset(fd, 0, NULL, &sw);
  432. if (ret <= 0) {
  433. error("sectok_reset failed: %s", sectok_get_sw(sw));
  434. goto done;
  435. }
  436. if ((cla = cyberflex_inq_class(fd)) < 0) {
  437. error("cyberflex_inq_class failed");
  438. goto done;
  439. }
  440. memcpy(AUT0, DEFAUT0, sizeof(DEFAUT0));
  441. if (cyberflex_verify_AUT0(fd, cla, AUT0, sizeof(DEFAUT0)) < 0) {
  442. if (get_AUT0(AUT0) < 0 ||
  443. cyberflex_verify_AUT0(fd, cla, AUT0, sizeof(DEFAUT0)) < 0) {
  444. memset(AUT0, 0, sizeof(DEFAUT0));
  445. error("smartcard passphrase incorrect");
  446. goto done;
  447. }
  448. }
  449. memset(AUT0, 0, sizeof(DEFAUT0));
  450. key_fid[0] = 0x00;
  451. key_fid[1] = 0x12;
  452. if (cyberflex_load_rsa_priv(fd, cla, key_fid, 5, 8*len, elements,
  453. &sw) < 0) {
  454. error("cyberflex_load_rsa_priv failed: %s", sectok_get_sw(sw));
  455. goto done;
  456. }
  457. if (!sectok_swOK(sw))
  458. goto done;
  459. logit("cyberflex_load_rsa_priv done");
  460. key_fid[0] = 0x73;
  461. key_fid[1] = 0x68;
  462. if (cyberflex_load_rsa_pub(fd, cla, key_fid, len, elements[5],
  463. &sw) < 0) {
  464. error("cyberflex_load_rsa_pub failed: %s", sectok_get_sw(sw));
  465. goto done;
  466. }
  467. if (!sectok_swOK(sw))
  468. goto done;
  469. logit("cyberflex_load_rsa_pub done");
  470. status = 0;
  471. done:
  472. memset(elements[0], '\0', BN_num_bytes(prv->rsa->q));
  473. memset(elements[1], '\0', BN_num_bytes(prv->rsa->p));
  474. memset(elements[2], '\0', BN_num_bytes(prv->rsa->iqmp));
  475. memset(elements[3], '\0', BN_num_bytes(prv->rsa->dmq1));
  476. memset(elements[4], '\0', BN_num_bytes(prv->rsa->dmp1));
  477. memset(elements[5], '\0', BN_num_bytes(prv->rsa->n));
  478. for (i = 0; i < NUM_RSA_KEY_ELEMENTS; i++)
  479. if (elements[i])
  480. xfree(elements[i]);
  481. if (fd != -1)
  482. sectok_close(fd);
  483. return (status);
  484. }
  485. char *
  486. sc_get_key_label(Key *key)
  487. {
  488. return xstrdup("smartcard key");
  489. }
  490. #endif /* SMARTCARD && USE_SECTOK */