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