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