res_crypto.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640
  1. /*
  2. * Asterisk -- A telephony toolkit for Linux.
  3. *
  4. * Provide Cryptographic Signature capability
  5. *
  6. * Copyright (C) 1999, Mark Spencer
  7. *
  8. * Mark Spencer <markster@linux-support.net>
  9. *
  10. * This program is free software, distributed under the terms of
  11. * the GNU General Public License
  12. */
  13. #include <sys/types.h>
  14. #include <asterisk/file.h>
  15. #include <asterisk/channel.h>
  16. #include <asterisk/logger.h>
  17. #include <asterisk/say.h>
  18. #include <asterisk/module.h>
  19. #include <asterisk/options.h>
  20. #include <asterisk/crypto.h>
  21. #include <asterisk/md5.h>
  22. #include <asterisk/cli.h>
  23. #include <asterisk/io.h>
  24. #include <openssl/ssl.h>
  25. #include <openssl/err.h>
  26. #include <stdio.h>
  27. #include <pthread.h>
  28. #include <dirent.h>
  29. #include <string.h>
  30. #include <errno.h>
  31. #include <unistd.h>
  32. #include <fcntl.h>
  33. #include "../asterisk.h"
  34. #include "../astconf.h"
  35. /*
  36. * Asterisk uses RSA keys with SHA-1 message digests for its
  37. * digital signatures. The choice of RSA is due to its higher
  38. * throughput on verification, and the choice of SHA-1 based
  39. * on the recently discovered collisions in MD5's compression
  40. * algorithm and recommendations of avoiding MD5 in new schemes
  41. * from various industry experts.
  42. *
  43. * We use OpenSSL to provide our crypto routines, although we never
  44. * actually use full-up SSL
  45. *
  46. */
  47. /*
  48. * XXX This module is not very thread-safe. It is for everyday stuff
  49. * like reading keys and stuff, but there are all kinds of weird
  50. * races with people running reload and key init at the same time
  51. * for example
  52. *
  53. * XXXX
  54. */
  55. static char base64[64];
  56. static char b2a[256];
  57. static ast_mutex_t keylock = AST_MUTEX_INITIALIZER;
  58. #define KEY_NEEDS_PASSCODE (1 << 16)
  59. struct ast_key {
  60. /* Name of entity */
  61. char name[80];
  62. /* File name */
  63. char fn[256];
  64. /* Key type (AST_KEY_PUB or AST_KEY_PRIV, along with flags from above) */
  65. int ktype;
  66. /* RSA structure (if successfully loaded) */
  67. RSA *rsa;
  68. /* Whether we should be deleted */
  69. int delme;
  70. /* FD for input (or -1 if no input allowed, or -2 if we needed input) */
  71. int infd;
  72. /* FD for output */
  73. int outfd;
  74. /* Last MD5 Digest */
  75. unsigned char digest[16];
  76. struct ast_key *next;
  77. };
  78. static struct ast_key *keys = NULL;
  79. #if 0
  80. static int fdprint(int fd, char *s)
  81. {
  82. return write(fd, s, strlen(s) + 1);
  83. }
  84. #endif
  85. static int pw_cb(char *buf, int size, int rwflag, void *userdata)
  86. {
  87. struct ast_key *key = (struct ast_key *)userdata;
  88. char prompt[256];
  89. int res;
  90. int tmp;
  91. if (key->infd > -1) {
  92. snprintf(prompt, sizeof(prompt), ">>>> passcode for %s key '%s': ",
  93. key->ktype == AST_KEY_PRIVATE ? "PRIVATE" : "PUBLIC", key->name);
  94. write(key->outfd, prompt, strlen(prompt));
  95. memset(buf, 0, sizeof(buf));
  96. tmp = ast_hide_password(key->infd);
  97. memset(buf, 0, size);
  98. res = read(key->infd, buf, size);
  99. ast_restore_tty(key->infd, tmp);
  100. if (buf[strlen(buf) -1] == '\n')
  101. buf[strlen(buf) - 1] = '\0';
  102. return strlen(buf);
  103. } else {
  104. /* Note that we were at least called */
  105. key->infd = -2;
  106. }
  107. return -1;
  108. }
  109. struct ast_key *ast_key_get(char *kname, int ktype)
  110. {
  111. struct ast_key *key;
  112. ast_mutex_lock(&keylock);
  113. key = keys;
  114. while(key) {
  115. if (!strcmp(kname, key->name) &&
  116. (ktype == key->ktype))
  117. break;
  118. key = key->next;
  119. }
  120. ast_mutex_unlock(&keylock);
  121. return key;
  122. }
  123. static struct ast_key *try_load_key (char *dir, char *fname, int ifd, int ofd, int *not2)
  124. {
  125. int ktype = 0;
  126. char *c = NULL;
  127. char ffname[256];
  128. char digest[16];
  129. FILE *f;
  130. struct MD5Context md5;
  131. struct ast_key *key;
  132. static int notice = 0;
  133. int found = 0;
  134. /* Make sure its name is a public or private key */
  135. if ((c = strstr(fname, ".pub")) && !strcmp(c, ".pub")) {
  136. ktype = AST_KEY_PUBLIC;
  137. } else if ((c = strstr(fname, ".key")) && !strcmp(c, ".key")) {
  138. ktype = AST_KEY_PRIVATE;
  139. } else
  140. return NULL;
  141. /* Get actual filename */
  142. snprintf(ffname, sizeof(ffname), "%s/%s", dir, fname);
  143. ast_mutex_lock(&keylock);
  144. key = keys;
  145. while(key) {
  146. /* Look for an existing version already */
  147. if (!strcasecmp(key->fn, ffname))
  148. break;
  149. key = key->next;
  150. }
  151. ast_mutex_unlock(&keylock);
  152. /* Open file */
  153. f = fopen(ffname, "r");
  154. if (!f) {
  155. ast_log(LOG_WARNING, "Unable to open key file %s: %s\n", ffname, strerror(errno));
  156. return NULL;
  157. }
  158. MD5Init(&md5);
  159. while(!feof(f)) {
  160. /* Calculate a "whatever" quality md5sum of the key */
  161. char buf[256];
  162. fgets(buf, sizeof(buf), f);
  163. if (!feof(f)) {
  164. MD5Update(&md5, buf, strlen(buf));
  165. }
  166. }
  167. MD5Final(digest, &md5);
  168. if (key) {
  169. /* If the MD5 sum is the same, and it isn't awaiting a passcode
  170. then this is far enough */
  171. if (!memcmp(digest, key->digest, 16) &&
  172. !(key->ktype & KEY_NEEDS_PASSCODE)) {
  173. fclose(f);
  174. key->delme = 0;
  175. return NULL;
  176. } else {
  177. /* Preserve keytype */
  178. ktype = key->ktype;
  179. /* Recycle the same structure */
  180. found++;
  181. }
  182. }
  183. /* Make fname just be the normal name now */
  184. *c = '\0';
  185. if (!key) {
  186. key = (struct ast_key *)malloc(sizeof(struct ast_key));
  187. if (!key) {
  188. ast_log(LOG_WARNING, "Out of memory\n");
  189. fclose(f);
  190. return NULL;
  191. }
  192. memset(key, 0, sizeof(struct ast_key));
  193. }
  194. /* At this point we have a key structure (old or new). Time to
  195. fill it with what we know */
  196. /* Gotta lock if this one already exists */
  197. if (found)
  198. ast_mutex_lock(&keylock);
  199. /* First the filename */
  200. strncpy(key->fn, ffname, sizeof(key->fn));
  201. /* Then the name */
  202. strncpy(key->name, fname, sizeof(key->name));
  203. key->ktype = ktype;
  204. /* Yes, assume we're going to be deleted */
  205. key->delme = 1;
  206. /* Keep the key type */
  207. memcpy(key->digest, digest, 16);
  208. /* Can I/O takes the FD we're given */
  209. key->infd = ifd;
  210. key->outfd = ofd;
  211. /* Reset the file back to the beginning */
  212. rewind(f);
  213. /* Now load the key with the right method */
  214. if (ktype == AST_KEY_PUBLIC)
  215. key->rsa = PEM_read_RSA_PUBKEY(f, NULL, pw_cb, key);
  216. else
  217. key->rsa = PEM_read_RSAPrivateKey(f, NULL, pw_cb, key);
  218. fclose(f);
  219. if (key->rsa) {
  220. /* Key loaded okay */
  221. key->ktype &= ~KEY_NEEDS_PASSCODE;
  222. if (option_verbose > 2)
  223. ast_verbose(VERBOSE_PREFIX_3 "Loaded %s key '%s'\n", key->ktype == AST_KEY_PUBLIC ? "PUBLIC" : "PRIVATE", key->name);
  224. if (option_debug)
  225. ast_log(LOG_DEBUG, "Key '%s' loaded OK\n", key->name);
  226. key->delme = 0;
  227. } else if (key->infd != -2) {
  228. ast_log(LOG_WARNING, "Key load %s '%s' failed\n",key->ktype == AST_KEY_PUBLIC ? "PUBLIC" : "PRIVATE", key->name);
  229. if (ofd > -1) {
  230. ERR_print_errors_fp(stderr);
  231. } else
  232. ERR_print_errors_fp(stderr);
  233. } else {
  234. ast_log(LOG_NOTICE, "Key '%s' needs passcode.\n", key->name);
  235. key->ktype |= KEY_NEEDS_PASSCODE;
  236. if (!notice) {
  237. if (!option_initcrypto)
  238. ast_log(LOG_NOTICE, "Add the '-i' flag to the asterisk command line if you want to automatically initialize passcodes at launch.\n");
  239. notice++;
  240. }
  241. /* Keep it anyway */
  242. key->delme = 0;
  243. /* Print final notice about "init keys" when done */
  244. *not2 = 1;
  245. }
  246. if (found)
  247. ast_mutex_unlock(&keylock);
  248. if (!found) {
  249. ast_mutex_lock(&keylock);
  250. key->next = keys;
  251. keys = key;
  252. ast_mutex_unlock(&keylock);
  253. }
  254. return key;
  255. }
  256. #if 0
  257. static void dump(unsigned char *src, int len)
  258. {
  259. int x;
  260. for (x=0;x<len;x++)
  261. printf("%02x", *(src++));
  262. printf("\n");
  263. }
  264. static char *binary(int y, int len)
  265. {
  266. static char res[80];
  267. int x;
  268. memset(res, 0, sizeof(res));
  269. for (x=0;x<len;x++) {
  270. if (y & (1 << x))
  271. res[(len - x - 1)] = '1';
  272. else
  273. res[(len - x - 1)] = '0';
  274. }
  275. return res;
  276. }
  277. #endif
  278. static int base64decode(unsigned char *dst, char *src, int max)
  279. {
  280. int cnt = 0;
  281. unsigned int byte = 0;
  282. unsigned int bits = 0;
  283. int incnt = 0;
  284. #if 0
  285. unsigned char *odst = dst;
  286. #endif
  287. while(*src && (cnt < max)) {
  288. /* Shift in 6 bits of input */
  289. byte <<= 6;
  290. byte |= (b2a[(int)(*src)]) & 0x3f;
  291. bits += 6;
  292. #if 0
  293. printf("Add: %c %s\n", *src, binary(b2a[(int)(*src)] & 0x3f, 6));
  294. #endif
  295. src++;
  296. incnt++;
  297. /* If we have at least 8 bits left over, take that character
  298. off the top */
  299. if (bits >= 8) {
  300. bits -= 8;
  301. *dst = (byte >> bits) & 0xff;
  302. #if 0
  303. printf("Remove: %02x %s\n", *dst, binary(*dst, 8));
  304. #endif
  305. dst++;
  306. cnt++;
  307. }
  308. }
  309. #if 0
  310. dump(odst, cnt);
  311. #endif
  312. /* Dont worry about left over bits, they're extra anyway */
  313. return cnt;
  314. }
  315. static int base64encode(char *dst, unsigned char *src, int srclen, int max)
  316. {
  317. int cnt = 0;
  318. unsigned int byte = 0;
  319. int bits = 0;
  320. int index;
  321. int cntin = 0;
  322. #if 0
  323. char *odst = dst;
  324. dump(src, srclen);
  325. #endif
  326. /* Reserve one bit for end */
  327. max--;
  328. while((cntin < srclen) && (cnt < max)) {
  329. byte <<= 8;
  330. #if 0
  331. printf("Add: %02x %s\n", *src, binary(*src, 8));
  332. #endif
  333. byte |= *(src++);
  334. bits += 8;
  335. cntin++;
  336. while((bits >= 6) && (cnt < max)) {
  337. bits -= 6;
  338. /* We want only the top */
  339. index = (byte >> bits) & 0x3f;
  340. *dst = base64[index];
  341. #if 0
  342. printf("Remove: %c %s\n", *dst, binary(index, 6));
  343. #endif
  344. dst++;
  345. cnt++;
  346. }
  347. }
  348. if (bits && (cnt < max)) {
  349. /* Add one last character for the remaining bits,
  350. padding the rest with 0 */
  351. byte <<= (6 - bits);
  352. index = (byte) & 0x3f;
  353. *(dst++) = base64[index];
  354. cnt++;
  355. }
  356. *dst = '\0';
  357. return cnt;
  358. }
  359. int ast_sign(struct ast_key *key, char *msg, char *sig)
  360. {
  361. unsigned char digest[20];
  362. unsigned char dsig[128];
  363. int siglen = sizeof(dsig);
  364. int res;
  365. if (key->ktype != AST_KEY_PRIVATE) {
  366. ast_log(LOG_WARNING, "Cannot sign with a private key\n");
  367. return -1;
  368. }
  369. /* Calculate digest of message */
  370. SHA1((unsigned char *)msg, strlen(msg), digest);
  371. /* Verify signature */
  372. res = RSA_sign(NID_sha1, digest, sizeof(digest), dsig, &siglen, key->rsa);
  373. if (!res) {
  374. ast_log(LOG_WARNING, "RSA Signature (key %s) failed\n", key->name);
  375. return -1;
  376. }
  377. if (siglen != sizeof(dsig)) {
  378. ast_log(LOG_WARNING, "Unexpected signature length %d, expecting %d\n", siglen, sizeof(dsig));
  379. return -1;
  380. }
  381. /* Success -- encode (256 bytes max as documented) */
  382. base64encode(sig, dsig, siglen, 256);
  383. return 0;
  384. }
  385. int ast_check_signature(struct ast_key *key, char *msg, char *sig)
  386. {
  387. unsigned char digest[20];
  388. unsigned char dsig[128];
  389. int res;
  390. if (key->ktype != AST_KEY_PUBLIC) {
  391. /* Okay, so of course you really *can* but for our purposes
  392. we're going to say you can't */
  393. ast_log(LOG_WARNING, "Cannot check message signature with a private key\n");
  394. return -1;
  395. }
  396. /* Decode signature */
  397. res = base64decode(dsig, sig, sizeof(dsig));
  398. if (res != sizeof(dsig)) {
  399. ast_log(LOG_WARNING, "Signature improper length (expect %d, got %d)\n", sizeof(dsig), res);
  400. return -1;
  401. }
  402. /* Calculate digest of message */
  403. SHA1((unsigned char *)msg, strlen(msg), digest);
  404. /* Verify signature */
  405. res = RSA_verify(NID_sha1, digest, sizeof(digest), dsig, sizeof(dsig), key->rsa);
  406. if (!res) {
  407. ast_log(LOG_DEBUG, "Key failed verification\n");
  408. return -1;
  409. }
  410. /* Pass */
  411. return 0;
  412. }
  413. static void crypto_load(int ifd, int ofd)
  414. {
  415. struct ast_key *key, *nkey, *last;
  416. DIR *dir;
  417. struct dirent *ent;
  418. int note = 0;
  419. /* Mark all keys for deletion */
  420. ast_mutex_lock(&keylock);
  421. key = keys;
  422. while(key) {
  423. key->delme = 1;
  424. key = key->next;
  425. }
  426. ast_mutex_unlock(&keylock);
  427. /* Load new keys */
  428. dir = opendir((char *)ast_config_AST_KEY_DIR);
  429. if (dir) {
  430. while((ent = readdir(dir))) {
  431. try_load_key((char *)ast_config_AST_KEY_DIR, ent->d_name, ifd, ofd, &note);
  432. }
  433. closedir(dir);
  434. } else
  435. ast_log(LOG_WARNING, "Unable to open key directory '%s'\n", (char *)ast_config_AST_KEY_DIR);
  436. if (note) {
  437. ast_log(LOG_NOTICE, "Please run the command 'init keys' to enter the passcodes for the keys\n");
  438. }
  439. ast_mutex_lock(&keylock);
  440. key = keys;
  441. last = NULL;
  442. while(key) {
  443. nkey = key->next;
  444. if (key->delme) {
  445. ast_log(LOG_DEBUG, "Deleting key %s type %d\n", key->name, key->ktype);
  446. /* Do the delete */
  447. if (last)
  448. last->next = nkey;
  449. else
  450. keys = nkey;
  451. if (key->rsa)
  452. RSA_free(key->rsa);
  453. free(key);
  454. } else
  455. last = key;
  456. key = nkey;
  457. }
  458. ast_mutex_unlock(&keylock);
  459. }
  460. static void md52sum(char *sum, unsigned char *md5)
  461. {
  462. int x;
  463. for (x=0;x<16;x++)
  464. sum += sprintf(sum, "%02x", *(md5++));
  465. }
  466. static int show_keys(int fd, int argc, char *argv[])
  467. {
  468. struct ast_key *key;
  469. char sum[16 * 2 + 1];
  470. ast_mutex_lock(&keylock);
  471. key = keys;
  472. ast_cli(fd, "%-18s %-8s %-16s %-33s\n", "Key Name", "Type", "Status", "Sum");
  473. while(key) {
  474. md52sum(sum, key->digest);
  475. ast_cli(fd, "%-18s %-8s %-16s %-33s\n", key->name,
  476. (key->ktype & 0xf) == AST_KEY_PUBLIC ? "PUBLIC" : "PRIVATE",
  477. key->ktype & KEY_NEEDS_PASSCODE ? "[Needs Passcode]" : "[Loaded]", sum);
  478. key = key->next;
  479. }
  480. ast_mutex_unlock(&keylock);
  481. return RESULT_SUCCESS;
  482. }
  483. static int init_keys(int fd, int argc, char *argv[])
  484. {
  485. struct ast_key *key;
  486. int ign;
  487. char *kn;
  488. char tmp[256];
  489. key = keys;
  490. while(key) {
  491. /* Reload keys that need pass codes now */
  492. if (key->ktype & KEY_NEEDS_PASSCODE) {
  493. kn = key->fn + strlen(ast_config_AST_KEY_DIR) + 1;
  494. strncpy(tmp, kn, sizeof(tmp));
  495. try_load_key((char *)ast_config_AST_KEY_DIR, tmp, fd, fd, &ign);
  496. }
  497. key = key->next;
  498. }
  499. return RESULT_SUCCESS;
  500. }
  501. static char show_key_usage[] =
  502. "Usage: show keys\n"
  503. " Displays information about RSA keys known by Asterisk\n";
  504. static char init_keys_usage[] =
  505. "Usage: init keys\n"
  506. " Initializes private keys (by reading in pass code from the user)\n";
  507. static struct ast_cli_entry cli_show_keys =
  508. { { "show", "keys", NULL }, show_keys, "Displays RSA key information", show_key_usage };
  509. static struct ast_cli_entry cli_init_keys =
  510. { { "init", "keys", NULL }, init_keys, "Initialize RSA key passcodes", init_keys_usage };
  511. static void base64_init(void)
  512. {
  513. int x;
  514. memset(b2a, -1, sizeof(b2a));
  515. /* Initialize base-64 Conversion table */
  516. for (x=0;x<26;x++) {
  517. /* A-Z */
  518. base64[x] = 'A' + x;
  519. b2a['A' + x] = x;
  520. /* a-z */
  521. base64[x + 26] = 'a' + x;
  522. b2a['a' + x] = x + 26;
  523. /* 0-9 */
  524. if (x < 10) {
  525. base64[x + 52] = '0' + x;
  526. b2a['0' + x] = x + 52;
  527. }
  528. }
  529. base64[62] = '+';
  530. base64[63] = '/';
  531. b2a[(int)'+'] = 62;
  532. b2a[(int)'/'] = 63;
  533. #if 0
  534. for (x=0;x<64;x++) {
  535. if (b2a[(int)base64[x]] != x) {
  536. fprintf(stderr, "!!! %d failed\n", x);
  537. } else
  538. fprintf(stderr, "--- %d passed\n", x);
  539. }
  540. #endif
  541. }
  542. static int crypto_init(void)
  543. {
  544. base64_init();
  545. SSL_library_init();
  546. ERR_load_crypto_strings();
  547. ast_cli_register(&cli_show_keys);
  548. ast_cli_register(&cli_init_keys);
  549. return 0;
  550. }
  551. int reload(void)
  552. {
  553. crypto_load(-1, -1);
  554. return 0;
  555. }
  556. int load_module(void)
  557. {
  558. crypto_init();
  559. if (option_initcrypto)
  560. crypto_load(STDIN_FILENO, STDOUT_FILENO);
  561. else
  562. crypto_load(-1, -1);
  563. return 0;
  564. }
  565. int unload_module(void)
  566. {
  567. /* Can't unload this once we're loaded */
  568. return -1;
  569. }
  570. char *description(void)
  571. {
  572. return "Cryptographic Digital Signatures";
  573. }
  574. int usecount(void)
  575. {
  576. /* We should never be unloaded */
  577. return 1;
  578. }
  579. char *key()
  580. {
  581. return ASTERISK_GPL_KEY;
  582. }