Wed Aug 18 22:34:31 2010

Asterisk developer's documentation


res_crypto.c File Reference

Provide Cryptographic Signature capability. More...

#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_keytry_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 = "a9c98e5d177805051735cb5b0b16b0a0" , .load = load_module, .unload = unload_module, .reload = reload }
static struct ast_module_infoast_module_info = &__mod_info
static struct ast_cli_entry cli_crypto []


Detailed Description

Provide Cryptographic Signature capability.

Author:
Mark Spencer <markster@digium.com>
ExtRef:
Uses the OpenSSL library, available at http://www.openssl.org/

Definition in file res_crypto.c.


Define Documentation

#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().


Function Documentation

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

See also:
ast_check_signature

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

See also:
ast_check_signature_bin

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

See also:
ast_decrypt_bin

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

See also:
ast_encrypt_bin

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

See also:
ast_key_get

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

See also:
ast_sign

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

See also:
ast_sign_bin

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 628 of file res_crypto.c.

static void __unreg_module ( void   )  [static]

Definition at line 628 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    ast_cli_register_multiple(cli_crypto, sizeof(cli_crypto) / sizeof(struct ast_cli_entry));
00589 
00590    /* Install ourselves into stubs */
00591    ast_key_get = __ast_key_get;
00592    ast_check_signature = __ast_check_signature;
00593    ast_check_signature_bin = __ast_check_signature_bin;
00594    ast_sign = __ast_sign;
00595    ast_sign_bin = __ast_sign_bin;
00596    ast_encrypt_bin = __ast_encrypt_bin;
00597    ast_decrypt_bin = __ast_decrypt_bin;
00598    return 0;
00599 }

static void crypto_load ( int  ifd,
int  ofd 
) [static]

refresh RSA keys from file

Parameters:
ifd file descriptor
ofd file descriptor
Returns:
void

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, &note);
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

Parameters:
e CLI command
cmd 
a list of CLI arguments
Returns:
CLI_SUCCESS

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

Parameters:
e CLI command
cmd 
a list of CLI arguments
Returns:
CLI_SUCCESS

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 607 of file res_crypto.c.

References AST_MODULE_LOAD_SUCCESS, ast_opt_init_keys, crypto_init(), and crypto_load().

00608 {
00609    crypto_init();
00610    if (ast_opt_init_keys)
00611       crypto_load(STDIN_FILENO, STDOUT_FILENO);
00612    else
00613       crypto_load(-1, -1);
00614    return AST_MODULE_LOAD_SUCCESS;
00615 }

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

Parameters:
buf 
size 
rwflag 
userdata 
Returns:
length of string,-1 on failure

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, ast_key::outfd, and prompt.

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 601 of file res_crypto.c.

References crypto_load().

00602 {
00603    crypto_load(-1, -1);
00604    return 0;
00605 }

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

Parameters:
dir directory string
fname name of file
ifd incoming file descriptor
ofd outgoing file descriptor
not2 
Return values:
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]

Definition at line 617 of file res_crypto.c.

00618 {
00619    /* Can't unload this once we're loaded */
00620    return -1;
00621 }


Variable Documentation

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 = "a9c98e5d177805051735cb5b0b16b0a0" , .load = load_module, .unload = unload_module, .reload = reload } [static]

Definition at line 628 of file res_crypto.c.

struct ast_module_info* ast_module_info = &__mod_info [static]

Definition at line 628 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().


Generated on Wed Aug 18 22:34:31 2010 for Asterisk - the Open Source PBX by  doxygen 1.4.7