00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #include "asterisk.h"
00031
00032 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 208990 $")
00033
00034 #include <sys/types.h>
00035 #include <openssl/ssl.h>
00036 #include <openssl/err.h>
00037 #include <stdio.h>
00038 #include <dirent.h>
00039 #include <string.h>
00040 #include <errno.h>
00041 #include <unistd.h>
00042 #include <fcntl.h>
00043
00044 #include "asterisk/file.h"
00045 #include "asterisk/channel.h"
00046 #include "asterisk/logger.h"
00047 #include "asterisk/say.h"
00048 #include "asterisk/module.h"
00049 #include "asterisk/options.h"
00050 #include "asterisk/crypto.h"
00051 #include "asterisk/md5.h"
00052 #include "asterisk/cli.h"
00053 #include "asterisk/io.h"
00054 #include "asterisk/lock.h"
00055 #include "asterisk/utils.h"
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079 AST_MUTEX_DEFINE_STATIC(keylock);
00080
00081 #define KEY_NEEDS_PASSCODE (1 << 16)
00082
00083 struct ast_key {
00084
00085 char name[80];
00086
00087 char fn[256];
00088
00089 int ktype;
00090
00091 RSA *rsa;
00092
00093 int delme;
00094
00095 int infd;
00096
00097 int outfd;
00098
00099 unsigned char digest[16];
00100 struct ast_key *next;
00101 };
00102
00103 static struct ast_key *keys = NULL;
00104
00105 static ast_mutex_t *ssl_locks;
00106
00107 static int ssl_num_locks;
00108
00109 static unsigned long ssl_threadid(void)
00110 {
00111 return (unsigned long)pthread_self();
00112 }
00113
00114 static void ssl_lock(int mode, int n, const char *file, int line)
00115 {
00116 if (n < 0 || n >= ssl_num_locks) {
00117 ast_log(LOG_ERROR, "OpenSSL is full of LIES!!! - "
00118 "ssl_num_locks '%d' - n '%d'\n",
00119 ssl_num_locks, n);
00120 return;
00121 }
00122
00123 if (mode & CRYPTO_LOCK) {
00124 ast_mutex_lock(&ssl_locks[n]);
00125 } else {
00126 ast_mutex_unlock(&ssl_locks[n]);
00127 }
00128 }
00129
00130 #if 0
00131 static int fdprint(int fd, char *s)
00132 {
00133 return write(fd, s, strlen(s) + 1);
00134 }
00135 #endif
00136 static int pw_cb(char *buf, int size, int rwflag, void *userdata)
00137 {
00138 struct ast_key *key = (struct ast_key *)userdata;
00139 char prompt[256];
00140 int res;
00141 int tmp;
00142 if (key->infd > -1) {
00143 snprintf(prompt, sizeof(prompt), ">>>> passcode for %s key '%s': ",
00144 key->ktype == AST_KEY_PRIVATE ? "PRIVATE" : "PUBLIC", key->name);
00145 if (write(key->outfd, prompt, strlen(prompt)) < 0) {
00146
00147 key->infd = -2;
00148 return -1;
00149 }
00150 memset(buf, 0, sizeof(buf));
00151 tmp = ast_hide_password(key->infd);
00152 memset(buf, 0, size);
00153 res = read(key->infd, buf, size);
00154 ast_restore_tty(key->infd, tmp);
00155 if (buf[strlen(buf) -1] == '\n')
00156 buf[strlen(buf) - 1] = '\0';
00157 return strlen(buf);
00158 } else {
00159
00160 key->infd = -2;
00161 }
00162 return -1;
00163 }
00164
00165 static struct ast_key *__ast_key_get(const char *kname, int ktype)
00166 {
00167 struct ast_key *key;
00168 ast_mutex_lock(&keylock);
00169 key = keys;
00170 while(key) {
00171 if (!strcmp(kname, key->name) &&
00172 (ktype == key->ktype))
00173 break;
00174 key = key->next;
00175 }
00176 ast_mutex_unlock(&keylock);
00177 return key;
00178 }
00179
00180 static struct ast_key *try_load_key (char *dir, char *fname, int ifd, int ofd, int *not2)
00181 {
00182 int ktype = 0;
00183 char *c = NULL;
00184 char ffname[256];
00185 unsigned char digest[16];
00186 FILE *f;
00187 struct MD5Context md5;
00188 struct ast_key *key;
00189 static int notice = 0;
00190 int found = 0;
00191
00192
00193
00194 if ((c = strstr(fname, ".pub")) && !strcmp(c, ".pub")) {
00195 ktype = AST_KEY_PUBLIC;
00196 } else if ((c = strstr(fname, ".key")) && !strcmp(c, ".key")) {
00197 ktype = AST_KEY_PRIVATE;
00198 } else
00199 return NULL;
00200
00201
00202 snprintf(ffname, sizeof(ffname), "%s/%s", dir, fname);
00203
00204 ast_mutex_lock(&keylock);
00205 key = keys;
00206 while(key) {
00207
00208 if (!strcasecmp(key->fn, ffname))
00209 break;
00210 key = key->next;
00211 }
00212 ast_mutex_unlock(&keylock);
00213
00214
00215 f = fopen(ffname, "r");
00216 if (!f) {
00217 ast_log(LOG_WARNING, "Unable to open key file %s: %s\n", ffname, strerror(errno));
00218 return NULL;
00219 }
00220 MD5Init(&md5);
00221 while(!feof(f)) {
00222
00223 char buf[256];
00224 memset(buf, 0, 256);
00225 if (fgets(buf, sizeof(buf), f)) {
00226 MD5Update(&md5, (unsigned char *) buf, strlen(buf));
00227 }
00228 }
00229 MD5Final(digest, &md5);
00230 if (key) {
00231
00232
00233 if (!memcmp(digest, key->digest, 16) &&
00234 !(key->ktype & KEY_NEEDS_PASSCODE)) {
00235 fclose(f);
00236 key->delme = 0;
00237 return NULL;
00238 } else {
00239
00240 ktype = key->ktype;
00241
00242 found++;
00243 }
00244 }
00245
00246
00247 *c = '\0';
00248 if (!key) {
00249 if (!(key = ast_calloc(1, sizeof(*key)))) {
00250 fclose(f);
00251 return NULL;
00252 }
00253 }
00254
00255
00256
00257 if (found)
00258 ast_mutex_lock(&keylock);
00259
00260 ast_copy_string(key->fn, ffname, sizeof(key->fn));
00261
00262 ast_copy_string(key->name, fname, sizeof(key->name));
00263 key->ktype = ktype;
00264
00265 key->delme = 1;
00266
00267 memcpy(key->digest, digest, 16);
00268
00269 key->infd = ifd;
00270 key->outfd = ofd;
00271
00272 rewind(f);
00273
00274 if (ktype == AST_KEY_PUBLIC)
00275 key->rsa = PEM_read_RSA_PUBKEY(f, NULL, pw_cb, key);
00276 else
00277 key->rsa = PEM_read_RSAPrivateKey(f, NULL, pw_cb, key);
00278 fclose(f);
00279 if (key->rsa) {
00280 if (RSA_size(key->rsa) == 128) {
00281
00282 key->ktype &= ~KEY_NEEDS_PASSCODE;
00283 if (option_verbose > 2)
00284 ast_verbose(VERBOSE_PREFIX_3 "Loaded %s key '%s'\n", key->ktype == AST_KEY_PUBLIC ? "PUBLIC" : "PRIVATE", key->name);
00285 if (option_debug)
00286 ast_log(LOG_DEBUG, "Key '%s' loaded OK\n", key->name);
00287 key->delme = 0;
00288 } else
00289 ast_log(LOG_NOTICE, "Key '%s' is not expected size.\n", key->name);
00290 } else if (key->infd != -2) {
00291 ast_log(LOG_WARNING, "Key load %s '%s' failed\n",key->ktype == AST_KEY_PUBLIC ? "PUBLIC" : "PRIVATE", key->name);
00292 if (ofd > -1) {
00293 ERR_print_errors_fp(stderr);
00294 } else
00295 ERR_print_errors_fp(stderr);
00296 } else {
00297 ast_log(LOG_NOTICE, "Key '%s' needs passcode.\n", key->name);
00298 key->ktype |= KEY_NEEDS_PASSCODE;
00299 if (!notice) {
00300 if (!ast_opt_init_keys)
00301 ast_log(LOG_NOTICE, "Add the '-i' flag to the asterisk command line if you want to automatically initialize passcodes at launch.\n");
00302 notice++;
00303 }
00304
00305 key->delme = 0;
00306
00307 *not2 = 1;
00308 }
00309 if (found)
00310 ast_mutex_unlock(&keylock);
00311 if (!found) {
00312 ast_mutex_lock(&keylock);
00313 key->next = keys;
00314 keys = key;
00315 ast_mutex_unlock(&keylock);
00316 }
00317 return key;
00318 }
00319
00320 #if 0
00321
00322 static void dump(unsigned char *src, int len)
00323 {
00324 int x;
00325 for (x=0;x<len;x++)
00326 printf("%02x", *(src++));
00327 printf("\n");
00328 }
00329
00330 static char *binary(int y, int len)
00331 {
00332 static char res[80];
00333 int x;
00334 memset(res, 0, sizeof(res));
00335 for (x=0;x<len;x++) {
00336 if (y & (1 << x))
00337 res[(len - x - 1)] = '1';
00338 else
00339 res[(len - x - 1)] = '0';
00340 }
00341 return res;
00342 }
00343
00344 #endif
00345
00346 static int __ast_sign_bin(struct ast_key *key, const char *msg, int msglen, unsigned char *dsig)
00347 {
00348 unsigned char digest[20];
00349 unsigned int siglen = 128;
00350 int res;
00351
00352 if (key->ktype != AST_KEY_PRIVATE) {
00353 ast_log(LOG_WARNING, "Cannot sign with a public key\n");
00354 return -1;
00355 }
00356
00357
00358 SHA1((unsigned char *)msg, msglen, digest);
00359
00360
00361 res = RSA_sign(NID_sha1, digest, sizeof(digest), dsig, &siglen, key->rsa);
00362
00363 if (!res) {
00364 ast_log(LOG_WARNING, "RSA Signature (key %s) failed\n", key->name);
00365 return -1;
00366 }
00367
00368 if (siglen != 128) {
00369 ast_log(LOG_WARNING, "Unexpected signature length %d, expecting %d\n", (int)siglen, (int)128);
00370 return -1;
00371 }
00372
00373 return 0;
00374
00375 }
00376
00377 static int __ast_decrypt_bin(unsigned char *dst, const unsigned char *src, int srclen, struct ast_key *key)
00378 {
00379 int res;
00380 int pos = 0;
00381 if (key->ktype != AST_KEY_PRIVATE) {
00382 ast_log(LOG_WARNING, "Cannot decrypt with a public key\n");
00383 return -1;
00384 }
00385
00386 if (srclen % 128) {
00387 ast_log(LOG_NOTICE, "Tried to decrypt something not a multiple of 128 bytes\n");
00388 return -1;
00389 }
00390 while(srclen) {
00391
00392 res = RSA_private_decrypt(128, src, dst, key->rsa, RSA_PKCS1_OAEP_PADDING);
00393 if (res < 0)
00394 return -1;
00395 pos += res;
00396 src += 128;
00397 srclen -= 128;
00398 dst += res;
00399 }
00400 return pos;
00401 }
00402
00403 static int __ast_encrypt_bin(unsigned char *dst, const unsigned char *src, int srclen, struct ast_key *key)
00404 {
00405 int res;
00406 int bytes;
00407 int pos = 0;
00408 if (key->ktype != AST_KEY_PUBLIC) {
00409 ast_log(LOG_WARNING, "Cannot encrypt with a private key\n");
00410 return -1;
00411 }
00412
00413 while(srclen) {
00414 bytes = srclen;
00415 if (bytes > 128 - 41)
00416 bytes = 128 - 41;
00417
00418 res = RSA_public_encrypt(bytes, src, dst, key->rsa, RSA_PKCS1_OAEP_PADDING);
00419 if (res != 128) {
00420 ast_log(LOG_NOTICE, "How odd, encrypted size is %d\n", res);
00421 return -1;
00422 }
00423 src += bytes;
00424 srclen -= bytes;
00425 pos += res;
00426 dst += res;
00427 }
00428 return pos;
00429 }
00430
00431 static int __ast_sign(struct ast_key *key, char *msg, char *sig)
00432 {
00433 unsigned char dsig[128];
00434 int siglen = sizeof(dsig);
00435 int res;
00436 res = ast_sign_bin(key, msg, strlen(msg), dsig);
00437 if (!res)
00438
00439 ast_base64encode(sig, dsig, siglen, 256);
00440 return res;
00441
00442 }
00443
00444 static int __ast_check_signature_bin(struct ast_key *key, const char *msg, int msglen, const unsigned char *dsig)
00445 {
00446 unsigned char digest[20];
00447 int res;
00448
00449 if (key->ktype != AST_KEY_PUBLIC) {
00450
00451
00452 ast_log(LOG_WARNING, "Cannot check message signature with a private key\n");
00453 return -1;
00454 }
00455
00456
00457 SHA1((unsigned char *)msg, msglen, digest);
00458
00459
00460 res = RSA_verify(NID_sha1, digest, sizeof(digest), (unsigned char *)dsig, 128, key->rsa);
00461
00462 if (!res) {
00463 ast_log(LOG_DEBUG, "Key failed verification: %s\n", key->name);
00464 return -1;
00465 }
00466
00467 return 0;
00468 }
00469
00470 static int __ast_check_signature(struct ast_key *key, const char *msg, const char *sig)
00471 {
00472 unsigned char dsig[128];
00473 int res;
00474
00475
00476 res = ast_base64decode(dsig, sig, sizeof(dsig));
00477 if (res != sizeof(dsig)) {
00478 ast_log(LOG_WARNING, "Signature improper length (expect %d, got %d)\n", (int)sizeof(dsig), (int)res);
00479 return -1;
00480 }
00481 res = ast_check_signature_bin(key, msg, strlen(msg), dsig);
00482 return res;
00483 }
00484
00485 static void crypto_load(int ifd, int ofd)
00486 {
00487 struct ast_key *key, *nkey, *last;
00488 DIR *dir = NULL;
00489 struct dirent *ent;
00490 int note = 0;
00491
00492 ast_mutex_lock(&keylock);
00493 key = keys;
00494 while(key) {
00495 key->delme = 1;
00496 key = key->next;
00497 }
00498 ast_mutex_unlock(&keylock);
00499
00500 dir = opendir((char *)ast_config_AST_KEY_DIR);
00501 if (dir) {
00502 while((ent = readdir(dir))) {
00503 try_load_key((char *)ast_config_AST_KEY_DIR, ent->d_name, ifd, ofd, ¬e);
00504 }
00505 closedir(dir);
00506 } else
00507 ast_log(LOG_WARNING, "Unable to open key directory '%s'\n", (char *)ast_config_AST_KEY_DIR);
00508 if (note) {
00509 ast_log(LOG_NOTICE, "Please run the command 'init keys' to enter the passcodes for the keys\n");
00510 }
00511 ast_mutex_lock(&keylock);
00512 key = keys;
00513 last = NULL;
00514 while(key) {
00515 nkey = key->next;
00516 if (key->delme) {
00517 ast_log(LOG_DEBUG, "Deleting key %s type %d\n", key->name, key->ktype);
00518
00519 if (last)
00520 last->next = nkey;
00521 else
00522 keys = nkey;
00523 if (key->rsa)
00524 RSA_free(key->rsa);
00525 free(key);
00526 } else
00527 last = key;
00528 key = nkey;
00529 }
00530 ast_mutex_unlock(&keylock);
00531 }
00532
00533 static void md52sum(char *sum, unsigned char *md5)
00534 {
00535 int x;
00536 for (x=0;x<16;x++)
00537 sum += sprintf(sum, "%02x", *(md5++));
00538 }
00539
00540 static int show_keys(int fd, int argc, char *argv[])
00541 {
00542 struct ast_key *key;
00543 char sum[16 * 2 + 1];
00544 int count_keys = 0;
00545
00546 ast_mutex_lock(&keylock);
00547 key = keys;
00548 ast_cli(fd, "%-18s %-8s %-16s %-33s\n", "Key Name", "Type", "Status", "Sum");
00549 while(key) {
00550 md52sum(sum, key->digest);
00551 ast_cli(fd, "%-18s %-8s %-16s %-33s\n", key->name,
00552 (key->ktype & 0xf) == AST_KEY_PUBLIC ? "PUBLIC" : "PRIVATE",
00553 key->ktype & KEY_NEEDS_PASSCODE ? "[Needs Passcode]" : "[Loaded]", sum);
00554
00555 key = key->next;
00556 count_keys++;
00557 }
00558 ast_mutex_unlock(&keylock);
00559 ast_cli(fd, "%d known RSA keys.\n", count_keys);
00560 return RESULT_SUCCESS;
00561 }
00562
00563 static int init_keys(int fd, int argc, char *argv[])
00564 {
00565 struct ast_key *key;
00566 int ign;
00567 char *kn;
00568 char tmp[256] = "";
00569
00570 key = keys;
00571 while(key) {
00572
00573 if (key->ktype & KEY_NEEDS_PASSCODE) {
00574 kn = key->fn + strlen(ast_config_AST_KEY_DIR) + 1;
00575 ast_copy_string(tmp, kn, sizeof(tmp));
00576 try_load_key((char *)ast_config_AST_KEY_DIR, tmp, fd, fd, &ign);
00577 }
00578 key = key->next;
00579 }
00580 return RESULT_SUCCESS;
00581 }
00582
00583 static char show_key_usage[] =
00584 "Usage: keys show\n"
00585 " Displays information about RSA keys known by Asterisk\n";
00586
00587 static char init_keys_usage[] =
00588 "Usage: keys init\n"
00589 " Initializes private keys (by reading in pass code from the user)\n";
00590
00591 static struct ast_cli_entry cli_show_keys_deprecated = {
00592 { "show", "keys", NULL },
00593 show_keys, NULL,
00594 NULL };
00595
00596 static struct ast_cli_entry cli_init_keys_deprecated = {
00597 { "init", "keys", NULL },
00598 init_keys, NULL,
00599 NULL };
00600
00601 static struct ast_cli_entry cli_crypto[] = {
00602 { { "keys", "show", NULL },
00603 show_keys, "Displays RSA key information",
00604 show_key_usage, NULL, &cli_show_keys_deprecated },
00605
00606 { { "keys", "init", NULL },
00607 init_keys, "Initialize RSA key passcodes",
00608 init_keys_usage, NULL, &cli_init_keys_deprecated },
00609 };
00610
00611 static int crypto_init(void)
00612 {
00613 unsigned int i;
00614
00615 SSL_library_init();
00616 SSL_load_error_strings();
00617 ERR_load_crypto_strings();
00618 ERR_load_BIO_strings();
00619 OpenSSL_add_all_algorithms();
00620
00621
00622
00623 CRYPTO_set_id_callback(ssl_threadid);
00624
00625 ssl_num_locks = CRYPTO_num_locks();
00626 if (!(ssl_locks = ast_calloc(ssl_num_locks, sizeof(ssl_locks[0])))) {
00627 return AST_MODULE_LOAD_DECLINE;
00628 }
00629 for (i = 0; i < ssl_num_locks; i++) {
00630 ast_mutex_init(&ssl_locks[i]);
00631 }
00632 CRYPTO_set_locking_callback(ssl_lock);
00633
00634 ast_cli_register_multiple(cli_crypto, sizeof(cli_crypto) / sizeof(struct ast_cli_entry));
00635
00636
00637 ast_key_get = __ast_key_get;
00638 ast_check_signature = __ast_check_signature;
00639 ast_check_signature_bin = __ast_check_signature_bin;
00640 ast_sign = __ast_sign;
00641 ast_sign_bin = __ast_sign_bin;
00642 ast_encrypt_bin = __ast_encrypt_bin;
00643 ast_decrypt_bin = __ast_decrypt_bin;
00644
00645 return AST_MODULE_LOAD_SUCCESS;
00646 }
00647
00648 static int reload(void)
00649 {
00650 crypto_load(-1, -1);
00651 return 0;
00652 }
00653
00654 static int load_module(void)
00655 {
00656 crypto_init();
00657 if (ast_opt_init_keys)
00658 crypto_load(STDIN_FILENO, STDOUT_FILENO);
00659 else
00660 crypto_load(-1, -1);
00661 return 0;
00662 }
00663
00664 static int unload_module(void)
00665 {
00666
00667 return -1;
00668 }
00669
00670
00671 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "Cryptographic Digital Signatures",
00672 .load = load_module,
00673 .unload = unload_module,
00674 .reload = reload
00675 );