#include "asterisk.h"
#include "asterisk/paths.h"
#include <openssl/ssl.h>
#include <openssl/err.h>
#include <dirent.h>
#include "asterisk/module.h"
#include "asterisk/crypto.h"
#include "asterisk/md5.h"
#include "asterisk/cli.h"
#include "asterisk/io.h"
#include "asterisk/lock.h"
#include "asterisk/utils.h"
Go to the source code of this file.
Data Structures | |
struct | ast_key |
struct | keys |
Defines | |
#define | FORMAT "%-18s %-8s %-16s %-33s\n" |
#define | KEY_NEEDS_PASSCODE (1 << 16) |
Functions | |
static int | __ast_check_signature (struct ast_key *key, const char *msg, const char *sig) |
base64 decode then sent to __ast_check_signature_bin | |
static int | __ast_check_signature_bin (struct ast_key *key, const char *msg, int msglen, const unsigned char *dsig) |
check signature of a message | |
static int | __ast_decrypt_bin (unsigned char *dst, const unsigned char *src, int srclen, struct ast_key *key) |
decrypt a message | |
static int | __ast_encrypt_bin (unsigned char *dst, const unsigned char *src, int srclen, struct ast_key *key) |
encrypt a message | |
static struct ast_key * | __ast_key_get (const char *kname, int ktype) |
return the ast_key structure for name | |
static int | __ast_sign (struct ast_key *key, char *msg, char *sig) |
wrapper for __ast_sign_bin then base64 encode it | |
static int | __ast_sign_bin (struct ast_key *key, const char *msg, int msglen, unsigned char *dsig) |
signs outgoing message with public key | |
static void | __reg_module (void) |
static void | __unreg_module (void) |
static int | crypto_init (void) |
initialise the res_crypto module | |
static void | crypto_load (int ifd, int ofd) |
refresh RSA keys from file | |
static char * | handle_cli_keys_init (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
initialize all RSA keys | |
static char * | handle_cli_keys_show (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
show the list of RSA keys | |
static int | load_module (void) |
static void | md52sum (char *sum, unsigned char *md5) |
static int | pw_cb (char *buf, int size, int rwflag, void *userdata) |
setting of priv key | |
static int | reload (void) |
static struct ast_key * | try_load_key (const char *dir, const char *fname, int ifd, int ofd, int *not2) |
load RSA key from file | |
static int | unload_module (void) |
Variables | |
static struct ast_module_info | __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "Cryptographic Digital Signatures" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "068e67f60f50dd9ee86464c05884a49d" , .load = load_module, .unload = unload_module, .reload = reload } |
static const struct ast_module_info * | ast_module_info = &__mod_info |
static struct ast_cli_entry | cli_crypto [] |
Definition in file res_crypto.c.
#define FORMAT "%-18s %-8s %-16s %-33s\n" |
#define KEY_NEEDS_PASSCODE (1 << 16) |
Definition at line 63 of file res_crypto.c.
Referenced by handle_cli_keys_init(), handle_cli_keys_show(), and try_load_key().
static int __ast_check_signature | ( | struct ast_key * | key, | |
const char * | msg, | |||
const char * | sig | |||
) | [static] |
base64 decode then sent to __ast_check_signature_bin
Definition at line 421 of file res_crypto.c.
References ast_base64decode(), ast_check_signature_bin, ast_log(), and LOG_WARNING.
Referenced by crypto_init().
00422 { 00423 unsigned char dsig[128]; 00424 int res; 00425 00426 /* Decode signature */ 00427 if ((res = ast_base64decode(dsig, sig, sizeof(dsig))) != sizeof(dsig)) { 00428 ast_log(LOG_WARNING, "Signature improper length (expect %d, got %d)\n", (int)sizeof(dsig), (int)res); 00429 return -1; 00430 } 00431 00432 res = ast_check_signature_bin(key, msg, strlen(msg), dsig); 00433 00434 return res; 00435 }
static int __ast_check_signature_bin | ( | struct ast_key * | key, | |
const char * | msg, | |||
int | msglen, | |||
const unsigned char * | dsig | |||
) | [static] |
check signature of a message
Definition at line 392 of file res_crypto.c.
References ast_debug, AST_KEY_PUBLIC, ast_log(), ast_key::digest, ast_key::ktype, LOG_WARNING, ast_key::name, and ast_key::rsa.
Referenced by crypto_init().
00393 { 00394 unsigned char digest[20]; 00395 int res; 00396 00397 if (key->ktype != AST_KEY_PUBLIC) { 00398 /* Okay, so of course you really *can* but for our purposes 00399 we're going to say you can't */ 00400 ast_log(LOG_WARNING, "Cannot check message signature with a private key\n"); 00401 return -1; 00402 } 00403 00404 /* Calculate digest of message */ 00405 SHA1((unsigned char *)msg, msglen, digest); 00406 00407 /* Verify signature */ 00408 if (!(res = RSA_verify(NID_sha1, digest, sizeof(digest), (unsigned char *)dsig, 128, key->rsa))) { 00409 ast_debug(1, "Key failed verification: %s\n", key->name); 00410 return -1; 00411 } 00412 00413 /* Pass */ 00414 return 0; 00415 }
static int __ast_decrypt_bin | ( | unsigned char * | dst, | |
const unsigned char * | src, | |||
int | srclen, | |||
struct ast_key * | key | |||
) | [static] |
decrypt a message
Definition at line 315 of file res_crypto.c.
References AST_KEY_PRIVATE, ast_log(), ast_key::ktype, LOG_NOTICE, LOG_WARNING, and ast_key::rsa.
Referenced by crypto_init().
00316 { 00317 int res, pos = 0; 00318 00319 if (key->ktype != AST_KEY_PRIVATE) { 00320 ast_log(LOG_WARNING, "Cannot decrypt with a public key\n"); 00321 return -1; 00322 } 00323 00324 if (srclen % 128) { 00325 ast_log(LOG_NOTICE, "Tried to decrypt something not a multiple of 128 bytes\n"); 00326 return -1; 00327 } 00328 00329 while(srclen) { 00330 /* Process chunks 128 bytes at a time */ 00331 if ((res = RSA_private_decrypt(128, src, dst, key->rsa, RSA_PKCS1_OAEP_PADDING)) < 0) 00332 return -1; 00333 pos += res; 00334 src += 128; 00335 srclen -= 128; 00336 dst += res; 00337 } 00338 00339 return pos; 00340 }
static int __ast_encrypt_bin | ( | unsigned char * | dst, | |
const unsigned char * | src, | |||
int | srclen, | |||
struct ast_key * | key | |||
) | [static] |
encrypt a message
Definition at line 346 of file res_crypto.c.
References AST_KEY_PUBLIC, ast_log(), ast_key::ktype, LOG_NOTICE, LOG_WARNING, and ast_key::rsa.
Referenced by crypto_init().
00347 { 00348 int res, bytes, pos = 0; 00349 00350 if (key->ktype != AST_KEY_PUBLIC) { 00351 ast_log(LOG_WARNING, "Cannot encrypt with a private key\n"); 00352 return -1; 00353 } 00354 00355 while(srclen) { 00356 bytes = srclen; 00357 if (bytes > 128 - 41) 00358 bytes = 128 - 41; 00359 /* Process chunks 128-41 bytes at a time */ 00360 if ((res = RSA_public_encrypt(bytes, src, dst, key->rsa, RSA_PKCS1_OAEP_PADDING)) != 128) { 00361 ast_log(LOG_NOTICE, "How odd, encrypted size is %d\n", res); 00362 return -1; 00363 } 00364 src += bytes; 00365 srclen -= bytes; 00366 pos += res; 00367 dst += res; 00368 } 00369 return pos; 00370 }
static struct ast_key* __ast_key_get | ( | const char * | kname, | |
int | ktype | |||
) | [static] |
return the ast_key structure for name
Definition at line 128 of file res_crypto.c.
References AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_key::ktype, ast_key::list, and ast_key::name.
Referenced by crypto_init().
00129 { 00130 struct ast_key *key; 00131 00132 AST_RWLIST_RDLOCK(&keys); 00133 AST_RWLIST_TRAVERSE(&keys, key, list) { 00134 if (!strcmp(kname, key->name) && 00135 (ktype == key->ktype)) 00136 break; 00137 } 00138 AST_RWLIST_UNLOCK(&keys); 00139 00140 return key; 00141 }
static int __ast_sign | ( | struct ast_key * | key, | |
char * | msg, | |||
char * | sig | |||
) | [static] |
wrapper for __ast_sign_bin then base64 encode it
Definition at line 376 of file res_crypto.c.
References ast_base64encode(), and ast_sign_bin.
Referenced by crypto_init().
00377 { 00378 unsigned char dsig[128]; 00379 int siglen = sizeof(dsig), res; 00380 00381 if (!(res = ast_sign_bin(key, msg, strlen(msg), dsig))) 00382 /* Success -- encode (256 bytes max as documented) */ 00383 ast_base64encode(sig, dsig, siglen, 256); 00384 00385 return res; 00386 }
static int __ast_sign_bin | ( | struct ast_key * | key, | |
const char * | msg, | |||
int | msglen, | |||
unsigned char * | dsig | |||
) | [static] |
signs outgoing message with public key
Definition at line 282 of file res_crypto.c.
References AST_KEY_PRIVATE, ast_log(), ast_key::digest, ast_key::ktype, LOG_WARNING, ast_key::name, and ast_key::rsa.
Referenced by crypto_init().
00283 { 00284 unsigned char digest[20]; 00285 unsigned int siglen = 128; 00286 int res; 00287 00288 if (key->ktype != AST_KEY_PRIVATE) { 00289 ast_log(LOG_WARNING, "Cannot sign with a public key\n"); 00290 return -1; 00291 } 00292 00293 /* Calculate digest of message */ 00294 SHA1((unsigned char *)msg, msglen, digest); 00295 00296 /* Verify signature */ 00297 if (!(res = RSA_sign(NID_sha1, digest, sizeof(digest), dsig, &siglen, key->rsa))) { 00298 ast_log(LOG_WARNING, "RSA Signature (key %s) failed\n", key->name); 00299 return -1; 00300 } 00301 00302 if (siglen != 128) { 00303 ast_log(LOG_WARNING, "Unexpected signature length %d, expecting %d\n", (int)siglen, (int)128); 00304 return -1; 00305 } 00306 00307 return 0; 00308 00309 }
static void __reg_module | ( | void | ) | [static] |
Definition at line 630 of file res_crypto.c.
static void __unreg_module | ( | void | ) | [static] |
Definition at line 630 of file res_crypto.c.
static int crypto_init | ( | void | ) | [static] |
initialise the res_crypto module
Definition at line 586 of file res_crypto.c.
References __ast_check_signature(), __ast_check_signature_bin(), __ast_decrypt_bin(), __ast_encrypt_bin(), __ast_key_get(), __ast_sign(), __ast_sign_bin(), ast_check_signature, ast_check_signature_bin, ast_cli_register_multiple(), ast_decrypt_bin, ast_encrypt_bin, ast_key_get, ast_sign, ast_sign_bin, and cli_crypto.
Referenced by load_module().
00587 { 00588 SSL_library_init(); 00589 ERR_load_crypto_strings(); 00590 ast_cli_register_multiple(cli_crypto, sizeof(cli_crypto) / sizeof(struct ast_cli_entry)); 00591 00592 /* Install ourselves into stubs */ 00593 ast_key_get = __ast_key_get; 00594 ast_check_signature = __ast_check_signature; 00595 ast_check_signature_bin = __ast_check_signature_bin; 00596 ast_sign = __ast_sign; 00597 ast_sign_bin = __ast_sign_bin; 00598 ast_encrypt_bin = __ast_encrypt_bin; 00599 ast_decrypt_bin = __ast_decrypt_bin; 00600 return 0; 00601 }
static void crypto_load | ( | int | ifd, | |
int | ofd | |||
) | [static] |
refresh RSA keys from file
ifd | file descriptor | |
ofd | file descriptor |
Definition at line 443 of file res_crypto.c.
References ast_config_AST_KEY_DIR, ast_debug, ast_free, ast_log(), AST_RWLIST_REMOVE_CURRENT, AST_RWLIST_TRAVERSE, AST_RWLIST_TRAVERSE_SAFE_BEGIN, AST_RWLIST_TRAVERSE_SAFE_END, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_key::delme, dir, ast_key::ktype, ast_key::list, LOG_NOTICE, LOG_WARNING, ast_key::name, ast_key::rsa, and try_load_key().
Referenced by load_module(), and reload().
00444 { 00445 struct ast_key *key; 00446 DIR *dir = NULL; 00447 struct dirent *ent; 00448 int note = 0; 00449 00450 AST_RWLIST_WRLOCK(&keys); 00451 00452 /* Mark all keys for deletion */ 00453 AST_RWLIST_TRAVERSE(&keys, key, list) { 00454 key->delme = 1; 00455 } 00456 00457 /* Load new keys */ 00458 if ((dir = opendir(ast_config_AST_KEY_DIR))) { 00459 while((ent = readdir(dir))) { 00460 try_load_key(ast_config_AST_KEY_DIR, ent->d_name, ifd, ofd, ¬e); 00461 } 00462 closedir(dir); 00463 } else 00464 ast_log(LOG_WARNING, "Unable to open key directory '%s'\n", ast_config_AST_KEY_DIR); 00465 00466 if (note) 00467 ast_log(LOG_NOTICE, "Please run the command 'init keys' to enter the passcodes for the keys\n"); 00468 00469 /* Delete any keys that are no longer present */ 00470 AST_RWLIST_TRAVERSE_SAFE_BEGIN(&keys, key, list) { 00471 if (key->delme) { 00472 ast_debug(1, "Deleting key %s type %d\n", key->name, key->ktype); 00473 AST_RWLIST_REMOVE_CURRENT(list); 00474 if (key->rsa) 00475 RSA_free(key->rsa); 00476 ast_free(key); 00477 } 00478 } 00479 AST_RWLIST_TRAVERSE_SAFE_END; 00480 00481 AST_RWLIST_UNLOCK(&keys); 00482 }
static char* handle_cli_keys_init | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
initialize all RSA keys
e | CLI command | |
cmd | ||
a | list of CLI arguments |
Definition at line 544 of file res_crypto.c.
References ast_cli_args::argc, ast_config_AST_KEY_DIR, ast_copy_string(), AST_RWLIST_TRAVERSE_SAFE_BEGIN, AST_RWLIST_TRAVERSE_SAFE_END, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, ast_key::fn, KEY_NEEDS_PASSCODE, ast_key::ktype, ast_key::list, try_load_key(), and ast_cli_entry::usage.
00545 { 00546 struct ast_key *key; 00547 int ign; 00548 char *kn, tmp[256] = ""; 00549 00550 switch (cmd) { 00551 case CLI_INIT: 00552 e->command = "keys init"; 00553 e->usage = 00554 "Usage: keys init\n" 00555 " Initializes private keys (by reading in pass code from\n" 00556 " the user)\n"; 00557 return NULL; 00558 case CLI_GENERATE: 00559 return NULL; 00560 } 00561 00562 if (a->argc != 2) 00563 return CLI_SHOWUSAGE; 00564 00565 AST_RWLIST_WRLOCK(&keys); 00566 AST_RWLIST_TRAVERSE_SAFE_BEGIN(&keys, key, list) { 00567 /* Reload keys that need pass codes now */ 00568 if (key->ktype & KEY_NEEDS_PASSCODE) { 00569 kn = key->fn + strlen(ast_config_AST_KEY_DIR) + 1; 00570 ast_copy_string(tmp, kn, sizeof(tmp)); 00571 try_load_key(ast_config_AST_KEY_DIR, tmp, a->fd, a->fd, &ign); 00572 } 00573 } 00574 AST_RWLIST_TRAVERSE_SAFE_END 00575 AST_RWLIST_UNLOCK(&keys); 00576 00577 return CLI_SUCCESS; 00578 }
static char* handle_cli_keys_show | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
show the list of RSA keys
e | CLI command | |
cmd | ||
a | list of CLI arguments |
Definition at line 498 of file res_crypto.c.
References ast_cli(), AST_KEY_PUBLIC, AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, ast_key::digest, ast_cli_args::fd, FORMAT, KEY_NEEDS_PASSCODE, ast_key::ktype, ast_key::list, md52sum(), ast_key::name, and ast_cli_entry::usage.
00499 { 00500 #define FORMAT "%-18s %-8s %-16s %-33s\n" 00501 00502 struct ast_key *key; 00503 char sum[16 * 2 + 1]; 00504 int count_keys = 0; 00505 00506 switch (cmd) { 00507 case CLI_INIT: 00508 e->command = "keys show"; 00509 e->usage = 00510 "Usage: keys show\n" 00511 " Displays information about RSA keys known by Asterisk\n"; 00512 return NULL; 00513 case CLI_GENERATE: 00514 return NULL; 00515 } 00516 00517 ast_cli(a->fd, FORMAT, "Key Name", "Type", "Status", "Sum"); 00518 ast_cli(a->fd, FORMAT, "------------------", "--------", "----------------", "--------------------------------"); 00519 00520 AST_RWLIST_RDLOCK(&keys); 00521 AST_RWLIST_TRAVERSE(&keys, key, list) { 00522 md52sum(sum, key->digest); 00523 ast_cli(a->fd, FORMAT, key->name, 00524 (key->ktype & 0xf) == AST_KEY_PUBLIC ? "PUBLIC" : "PRIVATE", 00525 key->ktype & KEY_NEEDS_PASSCODE ? "[Needs Passcode]" : "[Loaded]", sum); 00526 count_keys++; 00527 } 00528 AST_RWLIST_UNLOCK(&keys); 00529 00530 ast_cli(a->fd, "\n%d known RSA keys.\n", count_keys); 00531 00532 return CLI_SUCCESS; 00533 00534 #undef FORMAT 00535 }
static int load_module | ( | void | ) | [static] |
Definition at line 609 of file res_crypto.c.
References AST_MODULE_LOAD_SUCCESS, ast_opt_init_keys, crypto_init(), and crypto_load().
00610 { 00611 crypto_init(); 00612 if (ast_opt_init_keys) 00613 crypto_load(STDIN_FILENO, STDOUT_FILENO); 00614 else 00615 crypto_load(-1, -1); 00616 return AST_MODULE_LOAD_SUCCESS; 00617 }
static void md52sum | ( | char * | sum, | |
unsigned char * | md5 | |||
) | [static] |
Definition at line 484 of file res_crypto.c.
Referenced by handle_cli_keys_show().
00485 { 00486 int x; 00487 for (x = 0; x < 16; x++) 00488 sum += sprintf(sum, "%02x", *(md5++)); 00489 }
static int pw_cb | ( | char * | buf, | |
int | size, | |||
int | rwflag, | |||
void * | userdata | |||
) | [static] |
setting of priv key
buf | ||
size | ||
rwflag | ||
userdata |
Definition at line 95 of file res_crypto.c.
References ast_hide_password(), AST_KEY_PRIVATE, ast_log(), ast_restore_tty(), errno, ast_key::infd, ast_key::ktype, LOG_WARNING, ast_key::name, and ast_key::outfd.
Referenced by try_load_key().
00096 { 00097 struct ast_key *key = (struct ast_key *)userdata; 00098 char prompt[256]; 00099 int res, tmp; 00100 00101 if (key->infd < 0) { 00102 /* Note that we were at least called */ 00103 key->infd = -2; 00104 return -1; 00105 } 00106 00107 snprintf(prompt, sizeof(prompt), ">>>> passcode for %s key '%s': ", 00108 key->ktype == AST_KEY_PRIVATE ? "PRIVATE" : "PUBLIC", key->name); 00109 if (write(key->outfd, prompt, strlen(prompt)) < 0) { 00110 ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno)); 00111 key->infd = -2; 00112 return -1; 00113 } 00114 memset(buf, 0, sizeof(buf)); 00115 tmp = ast_hide_password(key->infd); 00116 memset(buf, 0, size); 00117 res = read(key->infd, buf, size); 00118 ast_restore_tty(key->infd, tmp); 00119 if (buf[strlen(buf) -1] == '\n') 00120 buf[strlen(buf) - 1] = '\0'; 00121 return strlen(buf); 00122 }
static int reload | ( | void | ) | [static] |
Definition at line 603 of file res_crypto.c.
References crypto_load().
00604 { 00605 crypto_load(-1, -1); 00606 return 0; 00607 }
static struct ast_key* try_load_key | ( | const char * | dir, | |
const char * | fname, | |||
int | ifd, | |||
int | ofd, | |||
int * | not2 | |||
) | [static] |
load RSA key from file
dir | directory string | |
fname | name of file | |
ifd | incoming file descriptor | |
ofd | outgoing file descriptor | |
not2 |
key | on success. | |
NULL | on failure. |
Definition at line 153 of file res_crypto.c.
References ast_calloc, ast_copy_string(), ast_debug, AST_KEY_PRIVATE, AST_KEY_PUBLIC, ast_log(), ast_opt_init_keys, AST_RWLIST_INSERT_TAIL, AST_RWLIST_TRAVERSE, ast_verb, buf, ast_key::delme, ast_key::digest, errno, f, ast_key::fn, ast_key::infd, KEY_NEEDS_PASSCODE, ast_key::ktype, ast_key::list, LOG_NOTICE, LOG_WARNING, md5(), MD5Final(), MD5Init(), MD5Update(), ast_key::name, ast_key::outfd, pw_cb(), and ast_key::rsa.
Referenced by crypto_load(), and handle_cli_keys_init().
00154 { 00155 int ktype = 0, found = 0; 00156 char *c = NULL, ffname[256]; 00157 unsigned char digest[16]; 00158 FILE *f; 00159 struct MD5Context md5; 00160 struct ast_key *key; 00161 static int notice = 0; 00162 00163 /* Make sure its name is a public or private key */ 00164 if ((c = strstr(fname, ".pub")) && !strcmp(c, ".pub")) 00165 ktype = AST_KEY_PUBLIC; 00166 else if ((c = strstr(fname, ".key")) && !strcmp(c, ".key")) 00167 ktype = AST_KEY_PRIVATE; 00168 else 00169 return NULL; 00170 00171 /* Get actual filename */ 00172 snprintf(ffname, sizeof(ffname), "%s/%s", dir, fname); 00173 00174 /* Open file */ 00175 if (!(f = fopen(ffname, "r"))) { 00176 ast_log(LOG_WARNING, "Unable to open key file %s: %s\n", ffname, strerror(errno)); 00177 return NULL; 00178 } 00179 00180 MD5Init(&md5); 00181 while(!feof(f)) { 00182 /* Calculate a "whatever" quality md5sum of the key */ 00183 char buf[256] = ""; 00184 if (!fgets(buf, sizeof(buf), f)) { 00185 continue; 00186 } 00187 if (!feof(f)) 00188 MD5Update(&md5, (unsigned char *) buf, strlen(buf)); 00189 } 00190 MD5Final(digest, &md5); 00191 00192 /* Look for an existing key */ 00193 AST_RWLIST_TRAVERSE(&keys, key, list) { 00194 if (!strcasecmp(key->fn, ffname)) 00195 break; 00196 } 00197 00198 if (key) { 00199 /* If the MD5 sum is the same, and it isn't awaiting a passcode 00200 then this is far enough */ 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 /* Preserve keytype */ 00208 ktype = key->ktype; 00209 /* Recycle the same structure */ 00210 found++; 00211 } 00212 } 00213 00214 /* Make fname just be the normal name now */ 00215 *c = '\0'; 00216 if (!key) { 00217 if (!(key = ast_calloc(1, sizeof(*key)))) { 00218 fclose(f); 00219 return NULL; 00220 } 00221 } 00222 /* First the filename */ 00223 ast_copy_string(key->fn, ffname, sizeof(key->fn)); 00224 /* Then the name */ 00225 ast_copy_string(key->name, fname, sizeof(key->name)); 00226 key->ktype = ktype; 00227 /* Yes, assume we're going to be deleted */ 00228 key->delme = 1; 00229 /* Keep the key type */ 00230 memcpy(key->digest, digest, 16); 00231 /* Can I/O takes the FD we're given */ 00232 key->infd = ifd; 00233 key->outfd = ofd; 00234 /* Reset the file back to the beginning */ 00235 rewind(f); 00236 /* Now load the key with the right method */ 00237 if (ktype == AST_KEY_PUBLIC) 00238 key->rsa = PEM_read_RSA_PUBKEY(f, NULL, pw_cb, key); 00239 else 00240 key->rsa = PEM_read_RSAPrivateKey(f, NULL, pw_cb, key); 00241 fclose(f); 00242 if (key->rsa) { 00243 if (RSA_size(key->rsa) == 128) { 00244 /* Key loaded okay */ 00245 key->ktype &= ~KEY_NEEDS_PASSCODE; 00246 ast_verb(3, "Loaded %s key '%s'\n", key->ktype == AST_KEY_PUBLIC ? "PUBLIC" : "PRIVATE", key->name); 00247 ast_debug(1, "Key '%s' loaded OK\n", key->name); 00248 key->delme = 0; 00249 } else 00250 ast_log(LOG_NOTICE, "Key '%s' is not expected size.\n", key->name); 00251 } else if (key->infd != -2) { 00252 ast_log(LOG_WARNING, "Key load %s '%s' failed\n",key->ktype == AST_KEY_PUBLIC ? "PUBLIC" : "PRIVATE", key->name); 00253 if (ofd > -1) 00254 ERR_print_errors_fp(stderr); 00255 else 00256 ERR_print_errors_fp(stderr); 00257 } else { 00258 ast_log(LOG_NOTICE, "Key '%s' needs passcode.\n", key->name); 00259 key->ktype |= KEY_NEEDS_PASSCODE; 00260 if (!notice) { 00261 if (!ast_opt_init_keys) 00262 ast_log(LOG_NOTICE, "Add the '-i' flag to the asterisk command line if you want to automatically initialize passcodes at launch.\n"); 00263 notice++; 00264 } 00265 /* Keep it anyway */ 00266 key->delme = 0; 00267 /* Print final notice about "init keys" when done */ 00268 *not2 = 1; 00269 } 00270 00271 /* If this is a new key add it to the list */ 00272 if (!found) 00273 AST_RWLIST_INSERT_TAIL(&keys, key, list); 00274 00275 return key; 00276 }
static int unload_module | ( | void | ) | [static] |
struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "Cryptographic Digital Signatures" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "068e67f60f50dd9ee86464c05884a49d" , .load = load_module, .unload = unload_module, .reload = reload } [static] |
Definition at line 630 of file res_crypto.c.
const struct ast_module_info* ast_module_info = &__mod_info [static] |
Definition at line 630 of file res_crypto.c.
struct ast_cli_entry cli_crypto[] [static] |
Initial value:
{ { .handler = handle_cli_keys_show , .summary = "Displays RSA key information" ,__VA_ARGS__ }, { .handler = handle_cli_keys_init , .summary = "Initialize RSA key passcodes" ,__VA_ARGS__ } }
Definition at line 580 of file res_crypto.c.
Referenced by crypto_init().