Asterisk.org: Developer Documentation (28 Oct 2009)

Wed Oct 28 15:49:14 2009

## Asterisk developer's documentation

# res_crypto.c File Reference

Provide Cryptographic Signature capability. More...

`#include <sys/types.h>`
`#include <openssl/ssl.h>`
`#include <openssl/err.h>`
`#include <stdio.h>`
`#include <dirent.h>`
`#include <string.h>`
`#include <errno.h>`
`#include <unistd.h>`
`#include <fcntl.h>`
`#include "asterisk.h"`
`#include "asterisk/file.h"`
`#include "asterisk/channel.h"`
`#include "asterisk/logger.h"`
`#include "asterisk/say.h"`
`#include "asterisk/module.h"`
`#include "asterisk/options.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"`

Include dependency graph for res_crypto.c:

Go to the source code of this file.

## Data Structures

struct | ast_key

## Defines

#define | KEY_NEEDS_PASSCODE (1 << 16)

## Functions

static int | __ast_check_signature (struct ast_key *key, const char *msg, const char *sig)
static int | __ast_check_signature_bin (struct ast_key *key, const char *msg, int msglen, const unsigned char *dsig)
static int | __ast_decrypt_bin (unsigned char *dst, const unsigned char *src, int srclen, struct ast_key *key)
static int | __ast_encrypt_bin (unsigned char *dst, const unsigned char *src, int srclen, struct ast_key *key)
static struct ast_key * | __ast_key_get (const char *kname, int ktype)
static int | __ast_sign (struct ast_key *key, char *msg, char *sig)
static int | __ast_sign_bin (struct ast_key *key, const char *msg, int msglen, unsigned char *dsig)
| AST_MUTEX_DEFINE_STATIC (keylock)
static int | crypto_init (void)
static void | crypto_load (int ifd, int ofd)
char * | description (void)
| Provides a description of the module.
static int | init_keys (int fd, int argc, char *argv[])
char * | key ()
| Returns the ASTERISK_GPL_KEY.
int | load_module (void)
| Initialize the module.
static void | md52sum (char *sum, unsigned char *md5)
static int | pw_cb (char *buf, int size, int rwflag, void *userdata)
int | reload (void)
| Reload stuff.
static int | show_keys (int fd, int argc, char *argv[])
static struct ast_key * | try_load_key (char *dir, char *fname, int ifd, int ofd, int *not2)
int | unload_module (void)
| Cleanup all module structures, sockets, etc.
int | usecount (void)
| Provides a usecount.

## Variables

static struct ast_cli_entry | cli_init_keys
static struct ast_cli_entry | cli_show_keys
static char | init_keys_usage []
static struct ast_key * | keys = NULL
static char | show_key_usage []

## Detailed Description

Provide Cryptographic Signature capability.

Definition in file res_crypto.c.

## Define Documentation

#define KEY_NEEDS_PASSCODE (1 << 16)

Definition at line 76 of file res_crypto.c.

Referenced by init_keys(), show_keys(), and try_load_key().

## Function Documentation

static int __ast_check_signature | ( | struct ast_key * | key,
|  | const char * | msg,
|  | const char * | sig |
| ) |  |  | `[static]`

Definition at line 441 of file res_crypto.c.

References ast_base64decode(), ast_check_signature_bin, ast_log(), and LOG_WARNING.

Referenced by crypto_init().

    00442 {
    00443    unsigned char dsig[128];
    00444    int res;
    00445
    00446    /* Decode signature */
    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 }

static int __ast_check_signature_bin | ( | struct ast_key * | key,
|  | const char * | msg,
|  | int | msglen,
|  | const unsigned char * | dsig |
| ) |  |  | `[static]`

Definition at line 415 of file res_crypto.c.

References AST_KEY_PUBLIC, ast_log(), ast_key::digest, ast_key::ktype, LOG_DEBUG, LOG_WARNING, ast_key::name, and ast_key::rsa.

Referenced by crypto_init().

    00416 {
    00417    unsigned char digest[20];
    00418    int res;
    00419
    00420    if (key->ktype != AST_KEY_PUBLIC) {
    00421       /* Okay, so of course you really *can* but for our purposes
    00422          we're going to say you can't */
    00423       ast_log(LOG_WARNING, "Cannot check message signature with a private key\n");
    00424       return -1;
    00425    }
    00426
    00427    /* Calculate digest of message */
    00428    SHA1((unsigned char *)msg, msglen, digest);
    00429
    00430    /* Verify signature */
    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    /* Pass */
    00438    return 0;
    00439 }

static int __ast_decrypt_bin | ( | unsigned char * | dst,
|  | const unsigned char * | src,
|  | int | srclen,
|  | struct ast_key * | key |
| ) |  |  | `[static]`

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

    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       /* Process chunks 128 bytes at a time */
    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 }

static int __ast_encrypt_bin | ( | unsigned char * | dst,
|  | const unsigned char * | src,
|  | int | srclen,
|  | struct ast_key * | key |
| ) |  |  | `[static]`

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

    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       /* Process chunks 128-41 bytes at a time */
    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 }

static struct ast_key* __ast_key_get | ( | const char * | kname,
|  | int | ktype |
| ) |  |  | `[static, read]`

Definition at line 132 of file res_crypto.c.

References ast_mutex_lock(), ast_mutex_unlock(), key(), ast_key::ktype, ast_key::name, and ast_key::next.

Referenced by crypto_init().

    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 }

static int __ast_sign | ( | struct ast_key * | key,
|  | char * | msg,
|  | char * | sig |
| ) |  |  | `[static]`

Definition at line 402 of file res_crypto.c.

References ast_base64encode(), and ast_sign_bin.

Referenced by crypto_init().

    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       /* Success -- encode (256 bytes max as documented) */
    00410       ast_base64encode(sig, dsig, siglen, 256);
    00411    return res;
    00412
    00413 }

static int __ast_sign_bin | ( | struct ast_key * | key,
|  | const char * | msg,
|  | int | msglen,
|  | unsigned char * | dsig |
| ) |  |  | `[static]`

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

    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    /* Calculate digest of message */
    00329    SHA1((unsigned char *)msg, msglen, digest);
    00330
    00331    /* Verify signature */
    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 }

AST_MUTEX_DEFINE_STATIC | ( | keylock |  | ) |

static int crypto_init | ( | void |  | ) | `[static]`

Definition at line 568 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(), ast_decrypt_bin, ast_encrypt_bin, ast_key_get, ast_sign, and ast_sign_bin.

Referenced by load_module().

    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    /* Install ourselves into stubs */
    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 }

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

Definition at line 456 of file res_crypto.c.

References ast_config_AST_KEY_DIR, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_key::delme, free, key(), ast_key::ktype, last, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, ast_key::name, ast_key::next, ast_key::rsa, and try_load_key().

Referenced by load_module(), and reload().

    00457 {
    00458    struct ast_key *key, *nkey, *last;
    00459    DIR *dir = NULL;
    00460    struct dirent *ent;
    00461    int note = 0;
    00462    /* Mark all keys for deletion */
    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    /* Load new keys */
    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, &note);
    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          /* Do the delete */
    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 }

char* description | ( | void |  | ) |

Provides a description of the module.

Returns:
  a short description of your module

Definition at line 608 of file res_crypto.c.

    00609 {
    00610    return "Cryptographic Digital Signatures";
    00611 }

static int init_keys | ( | int | fd,
|  | int | argc,
|  | char * | argv[] |
| ) |  |  | `[static]`

Definition at line 534 of file res_crypto.c.

References ast_config_AST_KEY_DIR, ast_key::fn, key(), KEY_NEEDS_PASSCODE, ast_key::ktype, ast_key::next, RESULT_SUCCESS, and try_load_key().

    00535 {
    00536    struct ast_key *key;
    00537    int ign;
    00538    char *kn;
    00539    char tmp[256] = "";
    00540
    00541    key = keys;
    00542    while(key) {
    00543       /* Reload keys that need pass codes now */
    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 }

char* key | ( | void |  | ) |

Returns the ASTERISK_GPL_KEY.

This returns the ASTERISK_GPL_KEY, signifiying that you agree to the terms of the GPL stated in the ASTERISK_GPL_KEY. Your module will not load if it does not return the EXACT message:

     char *key(void) {
             return ASTERISK_GPL_KEY;
     }

Returns:
  ASTERISK_GPL_KEY

Definition at line 619 of file res_crypto.c.

References ASTERISK_GPL_KEY.

    00620 {
    00621    return ASTERISK_GPL_KEY;
    00622 }

int load_module | ( | void |  | ) |

Initialize the module.

This function is called at module load time. Put all code in here that needs to set up your module's hardware, software, registrations, etc.

Returns:
  This function should return 0 on success and non-zero on failure. If the module is not loaded successfully, Asterisk will call its unload_module() function.

Initialize the Agents module. This function is being called by Asterisk when loading the module. Among other thing it registers applications, cli commands and reads the cofiguration file.

Returns:
  int Always 0.

TE STUFF END

Definition at line 592 of file res_crypto.c.

References crypto_init(), crypto_load(), and option_initcrypto.

    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 }

static void md52sum | ( | char * | sum,
|  | unsigned char * | md5 |
| ) |  |  | `[static]`

Definition at line 504 of file res_crypto.c.

Referenced by show_keys().

    00505 {
    00506    int x;
    00507    for (x=0;x<16;x++)
    00508       sum += sprintf(sum, "%02x", *(md5++));
    00509 }

static int pw_cb | ( | char * | buf,
|  | int | size,
|  | int | rwflag,
|  | void * | userdata |
| ) |  |  | `[static]`

Definition at line 107 of file res_crypto.c.

References ast_hide_password(), AST_KEY_PRIVATE, ast_restore_tty(), ast_key::infd, key(), ast_key::ktype, ast_key::name, and ast_key::outfd.

Referenced by try_load_key().

    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       /* Note that we were at least called */
    00127       key->infd = -2;
    00128    }
    00129    return -1;
    00130 }

int reload | ( | void |  | ) |

Reload stuff.

This function is where any reload routines take place. Re-read config files, change signalling, whatever is appropriate on a reload.

Returns:
  The return value is not used.

Definition at line 586 of file res_crypto.c.

References crypto_load().

    00587 {
    00588    crypto_load(-1, -1);
    00589    return 0;
    00590 }

static int show_keys | ( | int | fd,
|  | int | argc,
|  | char * | argv[] |
| ) |  |  | `[static]`

Definition at line 511 of file res_crypto.c.

References ast_cli(), AST_KEY_PUBLIC, ast_mutex_lock(), ast_mutex_unlock(), ast_key::digest, key(), KEY_NEEDS_PASSCODE, ast_key::ktype, md52sum(), ast_key::name, ast_key::next, and RESULT_SUCCESS.

    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 }

static struct ast_key* try_load_key | ( | char * | dir,
|  | char * | fname,
|  | int | ifd,
|  | int | ofd,
|  | int * | not2 |
| ) |  |  | `[static, read]`

Definition at line 147 of file res_crypto.c.

References AST_KEY_PRIVATE, AST_KEY_PUBLIC, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), ast_key::delme, ast_key::digest, ast_key::fn, ast_key::infd, key(), KEY_NEEDS_PASSCODE, ast_key::ktype, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, malloc, MD5Final(), MD5Init(), MD5Update(), ast_key::name, ast_key::next, option_debug, option_initcrypto, option_verbose, ast_key::outfd, pw_cb(), ast_key::rsa, and VERBOSE_PREFIX_3.

Referenced by crypto_load(), and init_keys().

    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    /* Make sure its name is a public or private key */
    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    /* Get actual filename */
    00169    snprintf(ffname, sizeof(ffname), "%s/%s", dir, fname);
    00170
    00171    ast_mutex_lock(&keylock);
    00172    key = keys;
    00173    while(key) {
    00174       /* Look for an existing version already */
    00175       if (!strcasecmp(key->fn, ffname))
    00176          break;
    00177       key = key->next;
    00178    }
    00179    ast_mutex_unlock(&keylock);
    00180
    00181    /* Open file */
    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       /* Calculate a "whatever" quality md5sum of the key */
    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       /* 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       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    /* At this point we have a key structure (old or new).  Time to
    00226       fill it with what we know */
    00227    /* Gotta lock if this one already exists */
    00228    if (found)
    00229       ast_mutex_lock(&keylock);
    00230    /* First the filename */
    00231    ast_copy_string(key->fn, ffname, sizeof(key->fn));
    00232    /* Then the name */
    00233    ast_copy_string(key->name, fname, sizeof(key->name));
    00234    key->ktype = ktype;
    00235    /* Yes, assume we're going to be deleted */
    00236    key->delme = 1;
    00237    /* Keep the key type */
    00238    memcpy(key->digest, digest, 16);
    00239    /* Can I/O takes the FD we're given */
    00240    key->infd = ifd;
    00241    key->outfd = ofd;
    00242    /* Reset the file back to the beginning */
    00243    rewind(f);
    00244    /* Now load the key with the right method */
    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          /* Key loaded okay */
    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       /* Keep it anyway */
    00276       key->delme = 0;
    00277       /* Print final notice about "init keys" when done */
    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 }

int unload_module | ( | void |  | ) |

Cleanup all module structures, sockets, etc.

This is called at exit. Any registrations and memory allocations need to be unregistered and free'd here. Nothing else will do these for you (until exit).

Returns:
  Zero on success, or non-zero on error.

Standard module functions ...

Definition at line 602 of file res_crypto.c.

    00603 {
    00604    /* Can't unload this once we're loaded */
    00605    return -1;
    00606 }

int usecount | ( | void |  | ) |

Provides a usecount.

This function will be called by various parts of asterisk. Basically, all it has to do is to return a usecount when called. You will need to maintain your usecount within the module somewhere. The usecount should be how many channels provided by this module are in use.

Returns:
  The module's usecount.

Definition at line 613 of file res_crypto.c.

    00614 {
    00615    /* We should never be unloaded */
    00616    return 1;
    00617 }

## Variable Documentation

struct ast_cli_entry cli_init_keys`[static]`

Initial value:

    { { "init", "keys", NULL }, init_keys, "Initialize RSA key passcodes", init_keys_usage }

Definition at line 565 of file res_crypto.c.

struct ast_cli_entry cli_show_keys`[static]`

Initial value:

    { { "show", "keys", NULL }, show_keys, "Displays RSA key information", show_key_usage }

Definition at line 562 of file res_crypto.c.

char init_keys_usage[]`[static]`

Initial value:

    "Usage: init keys\n"
    "       Initializes private keys (by reading in pass code from the user)\n"

Definition at line 558 of file res_crypto.c.

struct ast_key* keys = NULL`[static]`

Definition at line 98 of file res_crypto.c.

Referenced by adsi_delete(), adsi_folders(), adsi_login(), adsi_message(), adsi_password(), adsi_status(), adsi_status2(), ast_db_deltree(), ast_db_gettree(), database_show(), database_showkey(), misdn_set_opt_exec(), and reply_digest().

char show_key_usage[]`[static]`

Initial value:

    "Usage: show keys\n"
    "       Displays information about RSA keys known by Asterisk\n"

Definition at line 554 of file res_crypto.c.