Provide Cryptographic Signature capability. More...
#include "asterisk.h"#include "asterisk/paths.h"#include <openssl/ssl.h>#include <openssl/err.h>#include <openssl/aes.h>#include <dirent.h>#include "asterisk/module.h"#include "asterisk/md5.h"#include "asterisk/cli.h"#include "asterisk/io.h"#include "asterisk/lock.h"#include "asterisk/utils.h"#include "asterisk/crypto.h"
Go to the source code of this file.
Data Structures | |
| struct | ast_key |
| struct | keys |
Defines | |
| #define | AST_API_MODULE |
| #define | FORMAT "%-18s %-8s %-16s %-33s\n" |
| #define | KEY_NEEDS_PASSCODE (1 << 16) |
Functions | |
| static void | __reg_module (void) |
| static void | __unreg_module (void) |
| void AST_OPTIONAL_API_NAME() | ast_aes_decrypt (const unsigned char *in, unsigned char *out, const ast_aes_decrypt_key *ctx) |
| AES decrypt data. | |
| void AST_OPTIONAL_API_NAME() | ast_aes_encrypt (const unsigned char *in, unsigned char *out, const ast_aes_encrypt_key *ctx) |
| AES encrypt data. | |
| int AST_OPTIONAL_API_NAME() | ast_aes_set_decrypt_key (const unsigned char *key, ast_aes_decrypt_key *ctx) |
| Set a decryption key. | |
| int AST_OPTIONAL_API_NAME() | ast_aes_set_encrypt_key (const unsigned char *key, ast_aes_encrypt_key *ctx) |
| Set an encryption key. | |
| int AST_OPTIONAL_API_NAME() | ast_check_signature (struct ast_key *key, const char *msg, const char *sig) |
| base64 decode then sent to __ast_check_signature_bin | |
| int AST_OPTIONAL_API_NAME() | ast_check_signature_bin (struct ast_key *key, const char *msg, int msglen, const unsigned char *dsig) |
| check signature of a message | |
| int AST_OPTIONAL_API_NAME() | ast_crypto_loaded (void) |
| int AST_OPTIONAL_API_NAME() | ast_decrypt_bin (unsigned char *dst, const unsigned char *src, int srclen, struct ast_key *key) |
| decrypt a message | |
| int AST_OPTIONAL_API_NAME() | ast_encrypt_bin (unsigned char *dst, const unsigned char *src, int srclen, struct ast_key *key) |
| encrypt a message | |
| struct ast_key *AST_OPTIONAL_API_NAME() | ast_key_get (const char *kname, int ktype) |
| return the ast_key structure for name | |
| int AST_OPTIONAL_API_NAME() | ast_sign (struct ast_key *key, char *msg, char *sig) |
| wrapper for __ast_sign_bin then base64 encode it | |
| int AST_OPTIONAL_API_NAME() | ast_sign_bin (struct ast_key *key, const char *msg, int msglen, unsigned char *dsig) |
| signs outgoing message with public key | |
| 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_GLOBAL_SYMBOLS | AST_MODFLAG_LOAD_ORDER , .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 = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, .reload = reload, .load_pri = AST_MODPRI_CHANNEL_DEPEND, } |
| static struct ast_module_info * | ast_module_info = &__mod_info |
| static struct ast_cli_entry | cli_crypto [] |
| static struct keys | keys |
Provide Cryptographic Signature capability.
Definition in file res_crypto.c.
| #define AST_API_MODULE |
Definition at line 51 of file res_crypto.c.
| #define FORMAT "%-18s %-8s %-16s %-33s\n" |
| #define KEY_NEEDS_PASSCODE (1 << 16) |
Definition at line 67 of file res_crypto.c.
Referenced by handle_cli_keys_init(), handle_cli_keys_show(), and try_load_key().
| static void __reg_module | ( | void | ) | [static] |
Definition at line 670 of file res_crypto.c.
| static void __unreg_module | ( | void | ) | [static] |
Definition at line 670 of file res_crypto.c.
| void AST_OPTIONAL_API_NAME() ast_aes_decrypt | ( | const unsigned char * | in, |
| unsigned char * | out, | ||
| const ast_aes_decrypt_key * | ctx | ||
| ) |
AES decrypt data.
| in | encrypted data |
| out | pointer to a buffer to hold the decrypted output |
| ctx | address of an aes encryption context filled in with ast_aes_set_decrypt_key |
Definition at line 476 of file res_crypto.c.
Referenced by aes_helper(), decrypt_memcpy(), and memcpy_decrypt().
{
return AES_decrypt(in, out, ctx);
}
| void AST_OPTIONAL_API_NAME() ast_aes_encrypt | ( | const unsigned char * | in, |
| unsigned char * | out, | ||
| const ast_aes_encrypt_key * | ctx | ||
| ) |
AES encrypt data.
| in | data to be encrypted |
| out | pointer to a buffer to hold the encrypted output |
| ctx | address of an aes encryption context filled in with ast_aes_set_encrypt_key |
Definition at line 471 of file res_crypto.c.
Referenced by aes_helper(), encrypt_memcpy(), and memcpy_encrypt().
{
return AES_encrypt(in, out, ctx);
}
| int AST_OPTIONAL_API_NAME() ast_aes_set_decrypt_key | ( | const unsigned char * | key, |
| ast_aes_decrypt_key * | ctx | ||
| ) |
Set a decryption key.
| key | a 16 char key |
| ctx | address of an aes encryption context |
| 0 | success |
| nonzero | failure |
Definition at line 466 of file res_crypto.c.
Referenced by aes_helper(), build_ecx_key(), build_encryption_keys(), check_key(), socket_process_helper(), and update_key().
{
return AES_set_decrypt_key(key, 128, ctx);
}
| int AST_OPTIONAL_API_NAME() ast_aes_set_encrypt_key | ( | const unsigned char * | key, |
| ast_aes_encrypt_key * | ctx | ||
| ) |
Set an encryption key.
| key | a 16 char key |
| ctx | address of an aes encryption context |
| 0 | success |
| nonzero | failure |
Definition at line 461 of file res_crypto.c.
Referenced by aes_helper(), build_ecx_key(), check_key(), and update_key().
{
return AES_set_encrypt_key(key, 128, ctx);
}
| int AST_OPTIONAL_API_NAME() ast_check_signature | ( | struct ast_key * | key, |
| const char * | msg, | ||
| const char * | sig | ||
| ) |
base64 decode then sent to __ast_check_signature_bin
Check the authenticity of a message signature using a given public key.
Definition at line 440 of file res_crypto.c.
References ast_base64decode(), ast_check_signature_bin(), ast_log(), and LOG_WARNING.
Referenced by authenticate_verify(), and register_verify().
{
unsigned char dsig[128];
int res;
/* Decode signature */
if ((res = ast_base64decode(dsig, sig, sizeof(dsig))) != sizeof(dsig)) {
ast_log(LOG_WARNING, "Signature improper length (expect %d, got %d)\n", (int)sizeof(dsig), (int)res);
return -1;
}
res = ast_check_signature_bin(key, msg, strlen(msg), dsig);
return res;
}
| int AST_OPTIONAL_API_NAME() ast_check_signature_bin | ( | struct ast_key * | key, |
| const char * | msg, | ||
| int | msglen, | ||
| const unsigned char * | dsig | ||
| ) |
check signature of a message
Check the authenticity of a message signature using a given public key.
Definition at line 411 of file res_crypto.c.
References ast_debug, AST_KEY_PUBLIC, ast_log(), ast_key::digest, LOG_WARNING, and SHA1.
Referenced by ast_check_signature(), and check_key().
{
unsigned char digest[20];
int res;
if (key->ktype != AST_KEY_PUBLIC) {
/* Okay, so of course you really *can* but for our purposes
we're going to say you can't */
ast_log(LOG_WARNING, "Cannot check message signature with a private key\n");
return -1;
}
/* Calculate digest of message */
SHA1((unsigned char *)msg, msglen, digest);
/* Verify signature */
if (!(res = RSA_verify(NID_sha1, digest, sizeof(digest), (unsigned char *)dsig, 128, key->rsa))) {
ast_debug(1, "Key failed verification: %s\n", key->name);
return -1;
}
/* Pass */
return 0;
}
| int AST_OPTIONAL_API_NAME() ast_crypto_loaded | ( | void | ) |
Definition at line 456 of file res_crypto.c.
{
return 1;
}
| int AST_OPTIONAL_API_NAME() ast_decrypt_bin | ( | unsigned char * | dst, |
| const unsigned char * | src, | ||
| int | srclen, | ||
| struct ast_key * | key | ||
| ) |
decrypt a message
Decrypt a message using a given private key.
Definition at line 331 of file res_crypto.c.
References AST_KEY_PRIVATE, ast_log(), LOG_NOTICE, and LOG_WARNING.
Referenced by check_key().
{
int res, pos = 0;
if (key->ktype != AST_KEY_PRIVATE) {
ast_log(LOG_WARNING, "Cannot decrypt with a public key\n");
return -1;
}
if (srclen % 128) {
ast_log(LOG_NOTICE, "Tried to decrypt something not a multiple of 128 bytes\n");
return -1;
}
while (srclen) {
/* Process chunks 128 bytes at a time */
if ((res = RSA_private_decrypt(128, src, dst, key->rsa, RSA_PKCS1_OAEP_PADDING)) < 0) {
return -1;
}
pos += res;
src += 128;
srclen -= 128;
dst += res;
}
return pos;
}
| int AST_OPTIONAL_API_NAME() ast_encrypt_bin | ( | unsigned char * | dst, |
| const unsigned char * | src, | ||
| int | srclen, | ||
| struct ast_key * | key | ||
| ) |
encrypt a message
Encrypt a message using a given private key.
Definition at line 363 of file res_crypto.c.
References AST_KEY_PUBLIC, ast_log(), LOG_NOTICE, and LOG_WARNING.
Referenced by update_key().
{
int res, bytes, pos = 0;
if (key->ktype != AST_KEY_PUBLIC) {
ast_log(LOG_WARNING, "Cannot encrypt with a private key\n");
return -1;
}
while (srclen) {
bytes = srclen;
if (bytes > 128 - 41) {
bytes = 128 - 41;
}
/* Process chunks 128-41 bytes at a time */
if ((res = RSA_public_encrypt(bytes, src, dst, key->rsa, RSA_PKCS1_OAEP_PADDING)) != 128) {
ast_log(LOG_NOTICE, "How odd, encrypted size is %d\n", res);
return -1;
}
src += bytes;
srclen -= bytes;
pos += res;
dst += res;
}
return pos;
}
| struct ast_key* AST_OPTIONAL_API_NAME() ast_key_get | ( | const char * | kname, |
| int | ktype | ||
| ) | [read] |
return the ast_key structure for name
Retrieve a key.
Definition at line 136 of file res_crypto.c.
References AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_key::ktype, and ast_key::name.
Referenced by authenticate(), authenticate_verify(), check_key(), register_verify(), and update_key().
{
struct ast_key *key;
AST_RWLIST_RDLOCK(&keys);
AST_RWLIST_TRAVERSE(&keys, key, list) {
if (!strcmp(kname, key->name) &&
(ktype == key->ktype)) {
break;
}
}
AST_RWLIST_UNLOCK(&keys);
return key;
}
| int AST_OPTIONAL_API_NAME() ast_sign | ( | struct ast_key * | key, |
| char * | msg, | ||
| char * | sig | ||
| ) |
wrapper for __ast_sign_bin then base64 encode it
Sign a message signature using a given private key.
Definition at line 394 of file res_crypto.c.
References ast_base64encode(), and ast_sign_bin().
Referenced by authenticate().
{
unsigned char dsig[128];
int siglen = sizeof(dsig), res;
if (!(res = ast_sign_bin(key, msg, strlen(msg), dsig))) {
/* Success -- encode (256 bytes max as documented) */
ast_base64encode(sig, dsig, siglen, 256);
}
return res;
}
| int AST_OPTIONAL_API_NAME() ast_sign_bin | ( | struct ast_key * | key, |
| const char * | msg, | ||
| int | msglen, | ||
| unsigned char * | dsig | ||
| ) |
signs outgoing message with public key
Sign a message signature using a given private key.
Definition at line 299 of file res_crypto.c.
References AST_KEY_PRIVATE, ast_log(), ast_key::digest, LOG_WARNING, and SHA1.
Referenced by ast_sign(), and update_key().
{
unsigned char digest[20];
unsigned int siglen = 128;
int res;
if (key->ktype != AST_KEY_PRIVATE) {
ast_log(LOG_WARNING, "Cannot sign with a public key\n");
return -1;
}
/* Calculate digest of message */
SHA1((unsigned char *)msg, msglen, digest);
/* Verify signature */
if (!(res = RSA_sign(NID_sha1, digest, sizeof(digest), dsig, &siglen, key->rsa))) {
ast_log(LOG_WARNING, "RSA Signature (key %s) failed\n", key->name);
return -1;
}
if (siglen != 128) {
ast_log(LOG_WARNING, "Unexpected signature length %d, expecting %d\n", (int)siglen, (int)128);
return -1;
}
return 0;
}
| static int crypto_init | ( | void | ) | [static] |
initialise the res_crypto module
Definition at line 635 of file res_crypto.c.
References ARRAY_LEN, ast_cli_register_multiple(), and cli_crypto.
Referenced by load_module().
{
ast_cli_register_multiple(cli_crypto, ARRAY_LEN(cli_crypto));
return 0;
}
| static void crypto_load | ( | int | ifd, |
| int | ofd | ||
| ) | [static] |
refresh RSA keys from file
| ifd | file descriptor |
| ofd | file descriptor |
Definition at line 487 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, ast_key::ktype, LOG_NOTICE, LOG_WARNING, ast_key::name, ast_key::rsa, and try_load_key().
Referenced by load_module(), and reload().
{
struct ast_key *key;
DIR *dir = NULL;
struct dirent *ent;
int note = 0;
AST_RWLIST_WRLOCK(&keys);
/* Mark all keys for deletion */
AST_RWLIST_TRAVERSE(&keys, key, list) {
key->delme = 1;
}
/* Load new keys */
if ((dir = opendir(ast_config_AST_KEY_DIR))) {
while ((ent = readdir(dir))) {
try_load_key(ast_config_AST_KEY_DIR, ent->d_name, ifd, ofd, ¬e);
}
closedir(dir);
} else {
ast_log(LOG_WARNING, "Unable to open key directory '%s'\n", ast_config_AST_KEY_DIR);
}
if (note) {
ast_log(LOG_NOTICE, "Please run the command 'keys init' to enter the passcodes for the keys\n");
}
/* Delete any keys that are no longer present */
AST_RWLIST_TRAVERSE_SAFE_BEGIN(&keys, key, list) {
if (key->delme) {
ast_debug(1, "Deleting key %s type %d\n", key->name, key->ktype);
AST_RWLIST_REMOVE_CURRENT(list);
if (key->rsa) {
RSA_free(key->rsa);
}
ast_free(key);
}
}
AST_RWLIST_TRAVERSE_SAFE_END;
AST_RWLIST_UNLOCK(&keys);
}
| 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 592 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, try_load_key(), and ast_cli_entry::usage.
{
struct ast_key *key;
int ign;
char *kn, tmp[256] = "";
switch (cmd) {
case CLI_INIT:
e->command = "keys init";
e->usage =
"Usage: keys init\n"
" Initializes private keys (by reading in pass code from\n"
" the user)\n";
return NULL;
case CLI_GENERATE:
return NULL;
}
if (a->argc != 2) {
return CLI_SHOWUSAGE;
}
AST_RWLIST_WRLOCK(&keys);
AST_RWLIST_TRAVERSE_SAFE_BEGIN(&keys, key, list) {
/* Reload keys that need pass codes now */
if (key->ktype & KEY_NEEDS_PASSCODE) {
kn = key->fn + strlen(ast_config_AST_KEY_DIR) + 1;
ast_copy_string(tmp, kn, sizeof(tmp));
try_load_key(ast_config_AST_KEY_DIR, tmp, a->fd, a->fd, &ign);
}
}
AST_RWLIST_TRAVERSE_SAFE_END
AST_RWLIST_UNLOCK(&keys);
return CLI_SUCCESS;
}
| 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 546 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, md52sum(), ast_key::name, and ast_cli_entry::usage.
{
#define FORMAT "%-18s %-8s %-16s %-33s\n"
struct ast_key *key;
char sum[16 * 2 + 1];
int count_keys = 0;
switch (cmd) {
case CLI_INIT:
e->command = "keys show";
e->usage =
"Usage: keys show\n"
" Displays information about RSA keys known by Asterisk\n";
return NULL;
case CLI_GENERATE:
return NULL;
}
ast_cli(a->fd, FORMAT, "Key Name", "Type", "Status", "Sum");
ast_cli(a->fd, FORMAT, "------------------", "--------", "----------------", "--------------------------------");
AST_RWLIST_RDLOCK(&keys);
AST_RWLIST_TRAVERSE(&keys, key, list) {
md52sum(sum, key->digest);
ast_cli(a->fd, FORMAT, key->name,
(key->ktype & 0xf) == AST_KEY_PUBLIC ? "PUBLIC" : "PRIVATE",
key->ktype & KEY_NEEDS_PASSCODE ? "[Needs Passcode]" : "[Loaded]", sum);
count_keys++;
}
AST_RWLIST_UNLOCK(&keys);
ast_cli(a->fd, "\n%d known RSA keys.\n", count_keys);
return CLI_SUCCESS;
#undef FORMAT
}
| static int load_module | ( | void | ) | [static] |
Definition at line 647 of file res_crypto.c.
References AST_MODULE_LOAD_SUCCESS, ast_opt_init_keys, crypto_init(), and crypto_load().
{
crypto_init();
if (ast_opt_init_keys) {
crypto_load(STDIN_FILENO, STDOUT_FILENO);
} else {
crypto_load(-1, -1);
}
return AST_MODULE_LOAD_SUCCESS;
}
| static void md52sum | ( | char * | sum, |
| unsigned char * | md5 | ||
| ) | [static] |
Definition at line 531 of file res_crypto.c.
Referenced by handle_cli_keys_show().
{
int x;
for (x = 0; x < 16; x++) {
sum += sprintf(sum, "%02x", *(md5++));
}
}
| static int pw_cb | ( | char * | buf, |
| int | size, | ||
| int | rwflag, | ||
| void * | userdata | ||
| ) | [static] |
setting of priv key
| buf | |
| size | |
| rwflag | |
| userdata |
Definition at line 99 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, ast_key::outfd, and prompt.
Referenced by try_load_key().
{
struct ast_key *key = (struct ast_key *)userdata;
char prompt[256];
int tmp;
int res;
if (key->infd < 0) {
/* Note that we were at least called */
key->infd = -2;
return -1;
}
snprintf(prompt, sizeof(prompt), ">>>> passcode for %s key '%s': ",
key->ktype == AST_KEY_PRIVATE ? "PRIVATE" : "PUBLIC", key->name);
if (write(key->outfd, prompt, strlen(prompt)) < 0) {
ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno));
key->infd = -2;
return -1;
}
tmp = ast_hide_password(key->infd);
memset(buf, 0, size);
res = read(key->infd, buf, size);
if (res == -1) {
ast_log(LOG_WARNING, "read() failed: %s\n", strerror(errno));
}
ast_restore_tty(key->infd, tmp);
if (buf[strlen(buf) -1] == '\n') {
buf[strlen(buf) - 1] = '\0';
}
return strlen(buf);
}
| static int reload | ( | void | ) | [static] |
Definition at line 641 of file res_crypto.c.
References crypto_load().
{
crypto_load(-1, -1);
return 0;
}
| static struct ast_key* try_load_key | ( | const char * | dir, |
| const char * | fname, | ||
| int | ifd, | ||
| int | ofd, | ||
| int * | not2 | ||
| ) | [static, read] |
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 162 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, ast_key::delme, ast_key::digest, errno, f, ast_key::fn, ast_key::infd, KEY_NEEDS_PASSCODE, ast_key::ktype, LOG_NOTICE, LOG_WARNING, MD5Final(), MD5Init(), MD5Update(), ast_key::name, ast_key::outfd, pw_cb(), and ast_key::rsa.
Referenced by crypto_load(), and handle_cli_keys_init().
{
int ktype = 0, found = 0;
char *c = NULL, ffname[256];
unsigned char digest[16];
FILE *f;
struct MD5Context md5;
struct ast_key *key;
static int notice = 0;
/* Make sure its name is a public or private key */
if ((c = strstr(fname, ".pub")) && !strcmp(c, ".pub")) {
ktype = AST_KEY_PUBLIC;
} else if ((c = strstr(fname, ".key")) && !strcmp(c, ".key")) {
ktype = AST_KEY_PRIVATE;
} else {
return NULL;
}
/* Get actual filename */
snprintf(ffname, sizeof(ffname), "%s/%s", dir, fname);
/* Open file */
if (!(f = fopen(ffname, "r"))) {
ast_log(LOG_WARNING, "Unable to open key file %s: %s\n", ffname, strerror(errno));
return NULL;
}
MD5Init(&md5);
while (!feof(f)) {
/* Calculate a "whatever" quality md5sum of the key */
char buf[256] = "";
if (!fgets(buf, sizeof(buf), f)) {
continue;
}
if (!feof(f)) {
MD5Update(&md5, (unsigned char *) buf, strlen(buf));
}
}
MD5Final(digest, &md5);
/* Look for an existing key */
AST_RWLIST_TRAVERSE(&keys, key, list) {
if (!strcasecmp(key->fn, ffname)) {
break;
}
}
if (key) {
/* If the MD5 sum is the same, and it isn't awaiting a passcode
then this is far enough */
if (!memcmp(digest, key->digest, 16) &&
!(key->ktype & KEY_NEEDS_PASSCODE)) {
fclose(f);
key->delme = 0;
return NULL;
} else {
/* Preserve keytype */
ktype = key->ktype;
/* Recycle the same structure */
found++;
}
}
/* Make fname just be the normal name now */
*c = '\0';
if (!key) {
if (!(key = ast_calloc(1, sizeof(*key)))) {
fclose(f);
return NULL;
}
}
/* First the filename */
ast_copy_string(key->fn, ffname, sizeof(key->fn));
/* Then the name */
ast_copy_string(key->name, fname, sizeof(key->name));
key->ktype = ktype;
/* Yes, assume we're going to be deleted */
key->delme = 1;
/* Keep the key type */
memcpy(key->digest, digest, 16);
/* Can I/O takes the FD we're given */
key->infd = ifd;
key->outfd = ofd;
/* Reset the file back to the beginning */
rewind(f);
/* Now load the key with the right method */
if (ktype == AST_KEY_PUBLIC) {
key->rsa = PEM_read_RSA_PUBKEY(f, NULL, pw_cb, key);
} else {
key->rsa = PEM_read_RSAPrivateKey(f, NULL, pw_cb, key);
}
fclose(f);
if (key->rsa) {
if (RSA_size(key->rsa) == 128) {
/* Key loaded okay */
key->ktype &= ~KEY_NEEDS_PASSCODE;
ast_verb(3, "Loaded %s key '%s'\n", key->ktype == AST_KEY_PUBLIC ? "PUBLIC" : "PRIVATE", key->name);
ast_debug(1, "Key '%s' loaded OK\n", key->name);
key->delme = 0;
} else {
ast_log(LOG_NOTICE, "Key '%s' is not expected size.\n", key->name);
}
} else if (key->infd != -2) {
ast_log(LOG_WARNING, "Key load %s '%s' failed\n",key->ktype == AST_KEY_PUBLIC ? "PUBLIC" : "PRIVATE", key->name);
if (ofd > -1) {
ERR_print_errors_fp(stderr);
} else {
ERR_print_errors_fp(stderr);
}
} else {
ast_log(LOG_NOTICE, "Key '%s' needs passcode.\n", key->name);
key->ktype |= KEY_NEEDS_PASSCODE;
if (!notice) {
if (!ast_opt_init_keys) {
ast_log(LOG_NOTICE, "Add the '-i' flag to the asterisk command line if you want to automatically initialize passcodes at launch.\n");
}
notice++;
}
/* Keep it anyway */
key->delme = 0;
/* Print final notice about "keys init" when done */
*not2 = 1;
}
/* If this is a new key add it to the list */
if (!found) {
AST_RWLIST_INSERT_TAIL(&keys, key, list);
}
return key;
}
| static int unload_module | ( | void | ) | [static] |
Definition at line 658 of file res_crypto.c.
{
/* Can't unload this once we're loaded */
return -1;
}
struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_GLOBAL_SYMBOLS | AST_MODFLAG_LOAD_ORDER , .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 = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, .reload = reload, .load_pri = AST_MODPRI_CHANNEL_DEPEND, } [static] |
< Since we don't have a config file, we could move up to REALTIME_DEPEND, if necessary
Definition at line 670 of file res_crypto.c.
struct ast_module_info* ast_module_info = &__mod_info [static] |
Definition at line 670 of file res_crypto.c.
struct ast_cli_entry cli_crypto[] [static] |
{
AST_CLI_DEFINE(handle_cli_keys_show, "Displays RSA key information"),
AST_CLI_DEFINE(handle_cli_keys_init, "Initialize RSA key passcodes")
}
Definition at line 629 of file res_crypto.c.
Referenced by crypto_init().
Referenced by misdn_set_opt_exec().