Asterisk - The Open Source Telephony Project GIT-master-0bf3178
Data Structures | Macros | Functions | Variables
res_crypto.c File Reference

Provide Cryptographic Signature capability. More...

#include "asterisk.h"
#include <dirent.h>
#include <sys/stat.h>
#include <openssl/err.h>
#include <openssl/ssl.h>
#include <openssl/evp.h>
#include <openssl/md5.h>
#include <openssl/sha.h>
#include "asterisk/cli.h"
#include "asterisk/compat.h"
#include "asterisk/io.h"
#include "asterisk/linkedlists.h"
#include "asterisk/logger.h"
#include "asterisk/md5.h"
#include "asterisk/module.h"
#include "asterisk/options.h"
#include "asterisk/paths.h"
#include "asterisk/utils.h"
#include "asterisk/file.h"
#include "asterisk/crypto.h"
Include dependency graph for res_crypto.c:

Go to the source code of this file.

Data Structures

struct  ast_key
 
struct  crypto_load_on_file
 
struct  keys
 

Macros

#define AST_API_MODULE
 
#define FILE_MODE_BITS   (S_ISUID|S_ISGID|S_ISVTX|S_IRWXU|S_IRWXG|S_IRWXO)
 
#define FORMAT   "%-18s %-8s %-16s %-33s\n"
 
#define KEY_NEEDS_PASSCODE   (1 << 16)
 
#define RSA_PKCS1_OAEP_PADDING_SIZE   (1 + 2 * SHA_DIGEST_LENGTH)
 

Functions

static void __reg_module (void)
 
static void __unreg_module (void)
 
int AST_OPTIONAL_API_NAME() ast_aes_decrypt (const unsigned char *in, unsigned char *out, const ast_aes_decrypt_key *key)
 AES decrypt data. More...
 
int AST_OPTIONAL_API_NAME() ast_aes_encrypt (const unsigned char *in, unsigned char *out, const ast_aes_encrypt_key *key)
 AES encrypt data. More...
 
int AST_OPTIONAL_API_NAME() ast_aes_set_decrypt_key (const unsigned char *key, ast_aes_decrypt_key *ctx)
 Set a decryption key. More...
 
int AST_OPTIONAL_API_NAME() ast_aes_set_encrypt_key (const unsigned char *key, ast_aes_encrypt_key *ctx)
 Set an encryption key. More...
 
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 More...
 
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 More...
 
int AST_OPTIONAL_API_NAME() ast_crypto_loaded (void)
 
int AST_OPTIONAL_API_NAME() ast_crypto_reload (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 More...
 
int AST_OPTIONAL_API_NAME() ast_encrypt_bin (unsigned char *dst, const unsigned char *src, int srclen, struct ast_key *key)
 encrypt a message More...
 
struct ast_key *AST_OPTIONAL_API_NAME() ast_key_get (const char *kname, int ktype)
 return the ast_key structure for name More...
 
struct ast_moduleAST_MODULE_SELF_SYM (void)
 
int AST_OPTIONAL_API_NAME() ast_sign (struct ast_key *key, char *msg, char *sig)
 wrapper for __ast_sign_bin then base64 encode it More...
 
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 More...
 
static int crypto_init (void)
 initialise the res_crypto module More...
 
static void crypto_load (int ifd, int ofd)
 refresh RSA keys from file More...
 
static int crypto_load_cb (const char *directory, const char *file, void *obj)
 
static int evp_cipher_aes_decrypt (const unsigned char *in, unsigned char *out, unsigned inlen, const ast_aes_decrypt_key *key)
 
static int evp_cipher_aes_encrypt (const unsigned char *in, unsigned char *out, unsigned inlen, const ast_aes_encrypt_key *key)
 
static int evp_pkey_decrypt (EVP_PKEY *pkey, const unsigned char *in, unsigned inlen, unsigned char *out, unsigned *outlen, unsigned padding)
 
static int evp_pkey_encrypt (EVP_PKEY *pkey, const unsigned char *in, unsigned inlen, unsigned char *out, unsigned *outlen, unsigned padding)
 
static int evp_pkey_sign (EVP_PKEY *pkey, const unsigned char *in, unsigned inlen, unsigned char *sig, unsigned *siglen, unsigned padding)
 
static int evp_pkey_verify (EVP_PKEY *pkey, const unsigned char *in, unsigned inlen, const unsigned char *sig, unsigned siglen, unsigned padding)
 
static char * handle_cli_keys_init (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 initialize all RSA keys More...
 
static char * handle_cli_keys_show (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 show the list of RSA keys More...
 
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 More...
 
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 More...
 
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, .support_level = AST_MODULE_SUPPORT_CORE, .load = load_module, .unload = unload_module, .reload = reload, .load_pri = AST_MODPRI_CHANNEL_DEPEND, }
 
static const struct ast_module_infoast_module_info = &__mod_info
 
static struct ast_cli_entry cli_crypto []
 
static struct keys keys = { .first = NULL, .last = NULL, .lock = { PTHREAD_RWLOCK_INITIALIZER , NULL, {1, 0} } , }
 

Detailed Description

Provide Cryptographic Signature capability.

Author
Mark Spencer marks.nosp@m.ter@.nosp@m.digiu.nosp@m.m.co.nosp@m.m

Uses the OpenSSL library, available at http://www.openssl.org/

Definition in file res_crypto.c.

Macro Definition Documentation

◆ AST_API_MODULE

#define AST_API_MODULE

Definition at line 57 of file res_crypto.c.

◆ FILE_MODE_BITS

#define FILE_MODE_BITS   (S_ISUID|S_ISGID|S_ISVTX|S_IRWXU|S_IRWXG|S_IRWXO)

◆ FORMAT

#define FORMAT   "%-18s %-8s %-16s %-33s\n"

◆ KEY_NEEDS_PASSCODE

#define KEY_NEEDS_PASSCODE   (1 << 16)

Definition at line 73 of file res_crypto.c.

◆ RSA_PKCS1_OAEP_PADDING_SIZE

#define RSA_PKCS1_OAEP_PADDING_SIZE   (1 + 2 * SHA_DIGEST_LENGTH)

Definition at line 78 of file res_crypto.c.

Function Documentation

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 996 of file res_crypto.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 996 of file res_crypto.c.

◆ ast_aes_decrypt()

int AST_OPTIONAL_API_NAME() ast_aes_decrypt ( const unsigned char *  in,
unsigned char *  out,
const ast_aes_decrypt_key key 
)

AES decrypt data.

Parameters
inencrypted data
outpointer to a buffer to hold the decrypted output
keypointer to the ast_aes_decrypt_key to use for decryption
Return values
<=0 failure
otherwisenumber of bytes in output buffer

Definition at line 790 of file res_crypto.c.

791{
792 int res;
793
794 if ((res = evp_cipher_aes_decrypt(in, out, AST_CRYPTO_AES_BLOCKSIZE / 8, key)) <= 0) {
795 ast_log(LOG_ERROR, "AES decryption failed\n");
796 }
797 return res;
798}
#define ast_log
Definition: astobj2.c:42
#define AST_CRYPTO_AES_BLOCKSIZE
Definition: crypto.h:37
#define LOG_ERROR
static int evp_cipher_aes_decrypt(const unsigned char *in, unsigned char *out, unsigned inlen, const ast_aes_decrypt_key *key)
Definition: res_crypto.c:759
FILE * out
Definition: utils/frame.c:33
FILE * in
Definition: utils/frame.c:33

References AST_CRYPTO_AES_BLOCKSIZE, ast_log, evp_cipher_aes_decrypt(), in, LOG_ERROR, and out.

Referenced by aes_helper(), AST_TEST_DEFINE(), decrypt_memcpy(), and memcpy_decrypt().

◆ ast_aes_encrypt()

int AST_OPTIONAL_API_NAME() ast_aes_encrypt ( const unsigned char *  in,
unsigned char *  out,
const ast_aes_encrypt_key key 
)

AES encrypt data.

Parameters
indata to be encrypted
outpointer to a buffer to hold the encrypted output
keypointer to the ast_aes_encrypt_key to use for encryption
Return values
<=0 failure
otherwisenumber of bytes in output buffer

Definition at line 749 of file res_crypto.c.

750{
751 int res;
752
753 if ((res = evp_cipher_aes_encrypt(in, out, AST_CRYPTO_AES_BLOCKSIZE / 8, key)) <= 0) {
754 ast_log(LOG_ERROR, "AES encryption failed\n");
755 }
756 return res;
757}
static int evp_cipher_aes_encrypt(const unsigned char *in, unsigned char *out, unsigned inlen, const ast_aes_encrypt_key *key)
Definition: res_crypto.c:718

References AST_CRYPTO_AES_BLOCKSIZE, ast_log, evp_cipher_aes_encrypt(), in, LOG_ERROR, and out.

Referenced by aes_helper(), AST_TEST_DEFINE(), encrypt_memcpy(), and memcpy_encrypt().

◆ ast_aes_set_decrypt_key()

int AST_OPTIONAL_API_NAME() ast_aes_set_decrypt_key ( const unsigned char *  key,
ast_aes_decrypt_key ctx 
)

Set a decryption key.

Parameters
keya 16 char key
ctxaddress of an aes encryption context
Return values
0success
nonzerofailure

Definition at line 709 of file res_crypto.c.

710{
711 if (key == NULL || ctx == NULL) {
712 return -1;
713 }
714 memcpy(ctx->raw, key, AST_CRYPTO_AES_BLOCKSIZE / 8);
715 return 0;
716}
#define NULL
Definition: resample.c:96
unsigned char raw[AST_CRYPTO_AES_BLOCKSIZE/8]
Definition: crypto.h:40

References AST_CRYPTO_AES_BLOCKSIZE, and NULL.

Referenced by aes_helper(), AST_TEST_DEFINE(), build_ecx_key(), build_encryption_keys(), check_key(), socket_process_helper(), and update_key().

◆ ast_aes_set_encrypt_key()

int AST_OPTIONAL_API_NAME() ast_aes_set_encrypt_key ( const unsigned char *  key,
ast_aes_encrypt_key ctx 
)

Set an encryption key.

Parameters
keya 16 char key
ctxaddress of an aes encryption context
Return values
0success
nonzerofailure

Definition at line 700 of file res_crypto.c.

701{
702 if (key == NULL || ctx == NULL) {
703 return -1;
704 }
705 memcpy(ctx->raw, key, AST_CRYPTO_AES_BLOCKSIZE / 8);
706 return 0;
707}

References AST_CRYPTO_AES_BLOCKSIZE, and NULL.

Referenced by aes_helper(), AST_TEST_DEFINE(), build_ecx_key(), check_key(), and update_key().

◆ ast_check_signature()

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.

See also
ast_check_signature

Definition at line 673 of file res_crypto.c.

674{
675 unsigned char dsig[128];
676 int res;
677
678 /* Decode signature */
679 if ((res = ast_base64decode(dsig, sig, sizeof(dsig))) != sizeof(dsig)) {
680 ast_log(LOG_WARNING, "Signature improper length (expect %d, got %d)\n", (int)sizeof(dsig), (int)res);
681 return -1;
682 }
683
684 res = ast_check_signature_bin(key, msg, strlen(msg), dsig);
685
686 return res;
687}
#define LOG_WARNING
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
Definition: res_crypto.c:634
int ast_base64decode(unsigned char *dst, const char *src, int max)
Decode data from base64.
Definition: utils.c:296

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

Referenced by authenticate_verify(), and register_verify().

◆ 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

Check the authenticity of a message signature using a given public key.

See also
ast_check_signature_bin

Definition at line 634 of file res_crypto.c.

635{
636 unsigned char digest[SHA_DIGEST_LENGTH];
637 unsigned digestlen;
638 int res;
639 EVP_MD_CTX *ctx = NULL;
640
641 if (key->ktype != AST_KEY_PUBLIC) {
642 /* Okay, so of course you really *can* but for our purposes
643 we're going to say you can't */
644 ast_log(LOG_WARNING, "Cannot check message signature with a private key\n");
645 return -1;
646 }
647
648 /* Calculate digest of message */
649 ctx = EVP_MD_CTX_create();
650 if (ctx == NULL) {
651 ast_log(LOG_ERROR, "Out of memory\n");
652 return -1;
653 }
654 EVP_DigestInit(ctx, EVP_sha1());
655 EVP_DigestUpdate(ctx, msg, msglen);
656 EVP_DigestFinal(ctx, digest, &digestlen);
657 EVP_MD_CTX_destroy(ctx);
658
659 /* Verify signature */
660 if (!(res = evp_pkey_verify(key->pkey, (const unsigned char *)digest, sizeof(digest), (unsigned char *)dsig, 128, RSA_PKCS1_PADDING))) {
661 ast_debug(1, "Key failed verification: %s\n", key->name);
662 return -1;
663 }
664
665 /* Pass */
666 return 0;
667}
#define AST_KEY_PUBLIC
Definition: crypto.h:46
#define ast_debug(level,...)
Log a DEBUG message.
static int evp_pkey_verify(EVP_PKEY *pkey, const unsigned char *in, unsigned inlen, const unsigned char *sig, unsigned siglen, unsigned padding)
Definition: res_crypto.c:598
char name[80]
Definition: res_crypto.c:82
EVP_PKEY * pkey
Definition: res_crypto.c:88
int ktype
Definition: res_crypto.c:86

References ast_debug, AST_KEY_PUBLIC, ast_log, ast_key::digest, evp_pkey_verify(), ast_key::ktype, LOG_ERROR, LOG_WARNING, ast_key::name, NULL, and ast_key::pkey.

Referenced by ast_check_signature(), AST_TEST_DEFINE(), and check_key().

◆ ast_crypto_loaded()

int AST_OPTIONAL_API_NAME() ast_crypto_loaded ( void  )

Definition at line 689 of file res_crypto.c.

690{
691 return 1;
692}

Referenced by AST_TEST_DEFINE().

◆ ast_crypto_reload()

int AST_OPTIONAL_API_NAME() ast_crypto_reload ( void  )

Definition at line 694 of file res_crypto.c.

695{
696 crypto_load(-1, -1);
697 return 1;
698}
static void crypto_load(int ifd, int ofd)
refresh RSA keys from file
Definition: res_crypto.c:819

References crypto_load().

Referenced by AST_TEST_DEFINE().

◆ ast_decrypt_bin()

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.

See also
ast_decrypt_bin

Definition at line 472 of file res_crypto.c.

473{
474 int res;
475 unsigned pos = 0, dstlen, blocksize;
476
477 if (key->ktype != AST_KEY_PRIVATE) {
478 ast_log(LOG_WARNING, "Cannot decrypt with a public key\n");
479 return -1;
480 }
481
482 blocksize = EVP_PKEY_size(key->pkey);
483
484 if (srclen % blocksize) {
485 ast_log(LOG_NOTICE, "Tried to decrypt something not a multiple of %u bytes\n", blocksize);
486 return -1;
487 }
488
489 while (srclen > 0) {
490 /* Process chunks 128 bytes at a time */
491 dstlen = blocksize;
492 if ((res = evp_pkey_decrypt(key->pkey, src, blocksize, dst, &dstlen, RSA_PKCS1_OAEP_PADDING)) <= 0) {
493 return -1;
494 }
495 pos += dstlen;
496 src += blocksize;
497 srclen -= blocksize;
498 dst += dstlen;
499 }
500
501 return pos;
502}
#define AST_KEY_PRIVATE
Definition: crypto.h:47
#define LOG_NOTICE
static int evp_pkey_decrypt(EVP_PKEY *pkey, const unsigned char *in, unsigned inlen, unsigned char *out, unsigned *outlen, unsigned padding)
Definition: res_crypto.c:432

References AST_KEY_PRIVATE, ast_log, evp_pkey_decrypt(), ast_key::ktype, LOG_NOTICE, LOG_WARNING, and ast_key::pkey.

Referenced by AST_TEST_DEFINE(), and check_key().

◆ ast_encrypt_bin()

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.

See also
ast_encrypt_bin

Definition at line 549 of file res_crypto.c.

550{
551 unsigned bytes, pos = 0, dstlen, blocksize;
552 int res;
553
554 if (key->ktype != AST_KEY_PUBLIC) {
555 ast_log(LOG_WARNING, "Cannot encrypt with a private key\n");
556 return -1;
557 }
558
559 blocksize = EVP_PKEY_size(key->pkey);
560
561 while (srclen) {
562 bytes = srclen;
563 if (bytes > blocksize - RSA_PKCS1_OAEP_PADDING_SIZE) {
564 bytes = blocksize - RSA_PKCS1_OAEP_PADDING_SIZE;
565 }
566 /* Process chunks 128-41 bytes at a time */
567 dstlen = blocksize;
568 if ((res = evp_pkey_encrypt(key->pkey, src, bytes, dst, &dstlen, RSA_PKCS1_OAEP_PADDING)) != blocksize) {
569 ast_log(LOG_NOTICE, "How odd, encrypted size is %d\n", res);
570 return -1;
571 }
572 src += bytes;
573 srclen -= bytes;
574 pos += dstlen;
575 dst += dstlen;
576 }
577 return pos;
578}
#define RSA_PKCS1_OAEP_PADDING_SIZE
Definition: res_crypto.c:78
static int evp_pkey_encrypt(EVP_PKEY *pkey, const unsigned char *in, unsigned inlen, unsigned char *out, unsigned *outlen, unsigned padding)
Definition: res_crypto.c:504

References AST_KEY_PUBLIC, ast_log, evp_pkey_encrypt(), ast_key::ktype, LOG_NOTICE, LOG_WARNING, ast_key::pkey, and RSA_PKCS1_OAEP_PADDING_SIZE.

Referenced by AST_TEST_DEFINE(), and update_key().

◆ ast_key_get()

struct ast_key *AST_OPTIONAL_API_NAME() ast_key_get ( const char *  kname,
int  ktype 
)

return the ast_key structure for name

Retrieve a key.

See also
ast_key_get

Definition at line 149 of file res_crypto.c.

150{
151 struct ast_key *key;
152
154 AST_RWLIST_TRAVERSE(&keys, key, list) {
155 if (!strcmp(kname, key->name) &&
156 (ktype == key->ktype)) {
157 break;
158 }
159 }
161
162 return key;
163}
#define AST_RWLIST_RDLOCK(head)
Read locks a list.
Definition: linkedlists.h:78
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:151
#define AST_RWLIST_TRAVERSE
Definition: linkedlists.h:494

References AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_key::ktype, and ast_key::name.

Referenced by AST_TEST_DEFINE(), authenticate(), authenticate_verify(), check_key(), register_verify(), and update_key().

◆ AST_MODULE_SELF_SYM()

struct ast_module * AST_MODULE_SELF_SYM ( void  )

Definition at line 996 of file res_crypto.c.

◆ ast_sign()

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.

See also
ast_sign

Definition at line 584 of file res_crypto.c.

585{
586 /* assumes 1024 bit RSA key size */
587 unsigned char dsig[128];
588 int siglen = sizeof(dsig), res;
589
590 if (!(res = ast_sign_bin(key, msg, strlen(msg), dsig))) {
591 /* Success -- encode (256 bytes max as documented) */
592 ast_base64encode(sig, dsig, siglen, 256);
593 }
594
595 return res;
596}
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
Definition: res_crypto.c:390
int ast_base64encode(char *dst, const unsigned char *src, int srclen, int max)
Encode data in base64.
Definition: utils.c:406

References ast_base64encode(), and ast_sign_bin().

Referenced by authenticate().

◆ ast_sign_bin()

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.

See also
ast_sign_bin

Definition at line 390 of file res_crypto.c.

391{
392 unsigned char digest[SHA_DIGEST_LENGTH];
393 unsigned digestlen, siglen = 128;
394 int res;
395 EVP_MD_CTX *ctx = NULL;
396
397 if (key->ktype != AST_KEY_PRIVATE) {
398 ast_log(LOG_WARNING, "Cannot sign with a public key\n");
399 return -1;
400 }
401
402 if (siglen < EVP_PKEY_size(key->pkey)) {
403 ast_log(LOG_WARNING, "Signature buffer too small\n");
404 return -1;
405 }
406
407 /* Calculate digest of message */
408 ctx = EVP_MD_CTX_create();
409 if (ctx == NULL) {
410 ast_log(LOG_ERROR, "Out of memory\n");
411 return -1;
412 }
413 EVP_DigestInit(ctx, EVP_sha1());
414 EVP_DigestUpdate(ctx, msg, msglen);
415 EVP_DigestFinal(ctx, digest, &digestlen);
416 EVP_MD_CTX_destroy(ctx);
417
418 /* Verify signature */
419 if ((res = evp_pkey_sign(key->pkey, digest, sizeof(digest), dsig, &siglen, RSA_PKCS1_PADDING)) <= 0) {
420 ast_log(LOG_WARNING, "RSA Signature (key %s) failed %d\n", key->name, res);
421 return -1;
422 }
423
424 if (siglen != EVP_PKEY_size(key->pkey)) {
425 ast_log(LOG_WARNING, "Unexpected signature length %u, expecting %d\n", siglen, EVP_PKEY_size(key->pkey));
426 return -1;
427 }
428
429 return 0;
430}
static int evp_pkey_sign(EVP_PKEY *pkey, const unsigned char *in, unsigned inlen, unsigned char *sig, unsigned *siglen, unsigned padding)
Definition: res_crypto.c:351

References AST_KEY_PRIVATE, ast_log, ast_key::digest, evp_pkey_sign(), ast_key::ktype, LOG_ERROR, LOG_WARNING, ast_key::name, NULL, and ast_key::pkey.

Referenced by ast_sign(), AST_TEST_DEFINE(), and update_key().

◆ crypto_init()

static int crypto_init ( void  )
static

initialise the res_crypto module

Definition at line 959 of file res_crypto.c.

960{
962 return 0;
963}
#define ast_cli_register_multiple(e, len)
Register multiple commands.
Definition: cli.h:265
static struct ast_cli_entry cli_crypto[]
Definition: res_crypto.c:953
#define ARRAY_LEN(a)
Definition: utils.h:666

References ARRAY_LEN, ast_cli_register_multiple, and cli_crypto.

Referenced by load_module().

◆ crypto_load()

static void crypto_load ( int  ifd,
int  ofd 
)
static

refresh RSA keys from file

Parameters
ifdfile descriptor
ofdfile descriptor

Definition at line 819 of file res_crypto.c.

820{
821 struct ast_key *key;
822 struct crypto_load_on_file on_file = { ifd, ofd, 0 };
823
825
826 /* Mark all keys for deletion */
827 AST_RWLIST_TRAVERSE(&keys, key, list) {
828 key->delme = 1;
829 }
830
832 ast_log(LOG_WARNING, "Unable to open key directory '%s'\n", ast_config_AST_KEY_DIR);
833 }
834
835 if (on_file.note) {
836 ast_log(LOG_NOTICE, "Please run the command 'keys init' to enter the passcodes for the keys\n");
837 }
838
839 /* Delete any keys that are no longer present */
841 if (key->delme) {
842 ast_debug(1, "Deleting key %s type %d\n", key->name, key->ktype);
844 if (key->pkey) {
845 EVP_PKEY_free(key->pkey);
846 }
847 ast_free(key);
848 }
849 }
851
853}
#define ast_free(a)
Definition: astmm.h:180
int ast_file_read_dirs(const char *dir_name, ast_file_on_file on_file, void *obj, int max_depth)
Recursively iterate through files and directories up to max_depth.
Definition: file.c:1274
#define AST_RWLIST_REMOVE_CURRENT
Definition: linkedlists.h:570
#define AST_RWLIST_TRAVERSE_SAFE_BEGIN
Definition: linkedlists.h:545
#define AST_RWLIST_WRLOCK(head)
Write locks a list.
Definition: linkedlists.h:52
#define AST_RWLIST_TRAVERSE_SAFE_END
Definition: linkedlists.h:617
const char * ast_config_AST_KEY_DIR
Definition: options.c:161
static int crypto_load_cb(const char *directory, const char *file, void *obj)
Definition: res_crypto.c:806
int delme
Definition: res_crypto.c:90

References ast_config_AST_KEY_DIR, ast_debug, ast_file_read_dirs(), 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, crypto_load_cb(), ast_key::delme, crypto_load_on_file::ifd, ast_key::ktype, LOG_NOTICE, LOG_WARNING, ast_key::name, crypto_load_on_file::note, crypto_load_on_file::ofd, and ast_key::pkey.

Referenced by ast_crypto_reload(), load_module(), and reload().

◆ crypto_load_cb()

static int crypto_load_cb ( const char *  directory,
const char *  file,
void *  obj 
)
static

Definition at line 806 of file res_crypto.c.

807{
808 struct crypto_load_on_file *on_file = obj;
809
810 try_load_key(directory, file, on_file->ifd, on_file->ofd, &on_file->note);
811 return 0;
812}
static struct ast_key * try_load_key(const char *dir, const char *fname, int ifd, int ofd, int *not2)
load RSA key from file
Definition: res_crypto.c:175

References make_ari_stubs::file, crypto_load_on_file::ifd, crypto_load_on_file::note, crypto_load_on_file::ofd, and try_load_key().

Referenced by crypto_load().

◆ evp_cipher_aes_decrypt()

static int evp_cipher_aes_decrypt ( const unsigned char *  in,
unsigned char *  out,
unsigned  inlen,
const ast_aes_decrypt_key key 
)
static

Definition at line 759 of file res_crypto.c.

760{
761 EVP_CIPHER_CTX *ctx = NULL;
762 int res, outlen, finallen;
763 unsigned char final[AST_CRYPTO_AES_BLOCKSIZE / 8];
764
765 if ((ctx = EVP_CIPHER_CTX_new()) == NULL) {
766 return -1;
767 }
768
769 do {
770 if ((res = EVP_CipherInit(ctx, EVP_aes_128_ecb(), key->raw, NULL, 0)) <= 0) {
771 break;
772 }
773 EVP_CIPHER_CTX_set_padding(ctx, 0);
774 if ((res = EVP_CipherUpdate(ctx, out, &outlen, in, inlen)) <= 0) {
775 break;
776 }
777 /* for ECB, this is a no-op */
778 if ((res = EVP_CipherFinal(ctx, final, &finallen)) <= 0) {
779 break;
780 }
781
782 res = outlen;
783 } while (0);
784
785 EVP_CIPHER_CTX_free(ctx);
786
787 return res;
788}

References AST_CRYPTO_AES_BLOCKSIZE, in, NULL, out, and aes_key::raw.

Referenced by ast_aes_decrypt().

◆ evp_cipher_aes_encrypt()

static int evp_cipher_aes_encrypt ( const unsigned char *  in,
unsigned char *  out,
unsigned  inlen,
const ast_aes_encrypt_key key 
)
static

Definition at line 718 of file res_crypto.c.

719{
720 EVP_CIPHER_CTX *ctx = NULL;
721 int res, outlen, finallen;
722 unsigned char final[AST_CRYPTO_AES_BLOCKSIZE / 8];
723
724 if ((ctx = EVP_CIPHER_CTX_new()) == NULL) {
725 return -1;
726 }
727
728 do {
729 if ((res = EVP_CipherInit(ctx, EVP_aes_128_ecb(), key->raw, NULL, 1)) <= 0) {
730 break;
731 }
732 EVP_CIPHER_CTX_set_padding(ctx, 0);
733 if ((res = EVP_CipherUpdate(ctx, out, &outlen, in, inlen)) <= 0) {
734 break;
735 }
736 /* for ECB, this is a no-op */
737 if ((res = EVP_CipherFinal(ctx, final, &finallen)) <= 0) {
738 break;
739 }
740
741 res = outlen;
742 } while (0);
743
744 EVP_CIPHER_CTX_free(ctx);
745
746 return res;
747}

References AST_CRYPTO_AES_BLOCKSIZE, in, NULL, out, and aes_key::raw.

Referenced by ast_aes_encrypt().

◆ evp_pkey_decrypt()

static int evp_pkey_decrypt ( EVP_PKEY *  pkey,
const unsigned char *  in,
unsigned  inlen,
unsigned char *  out,
unsigned *  outlen,
unsigned  padding 
)
static

Definition at line 432 of file res_crypto.c.

433{
434 EVP_PKEY_CTX *ctx = NULL;
435 int res = -1;
436 size_t _outlen;
437
438 if (*outlen < EVP_PKEY_size(pkey)) {
439 return -1;
440 }
441
442 if (inlen != EVP_PKEY_size(pkey)) {
443 return -1;
444 }
445
446 if ((ctx = EVP_PKEY_CTX_new(pkey, NULL)) == NULL) {
447 return -1;
448 }
449
450 do {
451 if ((res = EVP_PKEY_decrypt_init(ctx)) <= 0) {
452 break;
453 }
454 if ((res = EVP_PKEY_CTX_set_rsa_padding(ctx, padding)) <= 0) {
455 break;
456 }
457 _outlen = *outlen;
458 if ((res = EVP_PKEY_decrypt(ctx, out, &_outlen, in, inlen)) <= 0) {
459 break;
460 }
461 res = *outlen = _outlen;
462 } while (0);
463
464 EVP_PKEY_CTX_free(ctx);
465 return res;
466}

References in, NULL, out, and ast_key::pkey.

Referenced by ast_decrypt_bin().

◆ evp_pkey_encrypt()

static int evp_pkey_encrypt ( EVP_PKEY *  pkey,
const unsigned char *  in,
unsigned  inlen,
unsigned char *  out,
unsigned *  outlen,
unsigned  padding 
)
static

Definition at line 504 of file res_crypto.c.

505{
506 EVP_PKEY_CTX *ctx = NULL;
507 int res = -1;
508 size_t _outlen;
509
510 if (padding != RSA_PKCS1_OAEP_PADDING) {
511 ast_log(LOG_WARNING, "Only OAEP padding is supported for now\n");
512 return -1;
513 }
514
515 if (inlen > EVP_PKEY_size(pkey) - RSA_PKCS1_OAEP_PADDING_SIZE) {
516 return -1;
517 }
518
519 if (*outlen < EVP_PKEY_size(pkey)) {
520 return -1;
521 }
522
523 do {
524 if ((ctx = EVP_PKEY_CTX_new(pkey, NULL)) == NULL) {
525 break;
526 }
527
528 if ((res = EVP_PKEY_encrypt_init(ctx)) <= 0) {
529 break;
530 }
531 if ((res = EVP_PKEY_CTX_set_rsa_padding(ctx, padding)) <= 0) {
532 break;
533 }
534 _outlen = *outlen;
535 if ((res = EVP_PKEY_encrypt(ctx, out, &_outlen, in, inlen)) <= 0) {
536 break;
537 }
538 res = *outlen = _outlen;
539 } while (0);
540
541 EVP_PKEY_CTX_free(ctx);
542 return res;
543}

References ast_log, in, LOG_WARNING, NULL, out, ast_key::pkey, and RSA_PKCS1_OAEP_PADDING_SIZE.

Referenced by ast_encrypt_bin().

◆ evp_pkey_sign()

static int evp_pkey_sign ( EVP_PKEY *  pkey,
const unsigned char *  in,
unsigned  inlen,
unsigned char *  sig,
unsigned *  siglen,
unsigned  padding 
)
static

Definition at line 351 of file res_crypto.c.

352{
353 EVP_PKEY_CTX *ctx = NULL;
354 int res = -1;
355 size_t _siglen;
356
357 if (*siglen < EVP_PKEY_size(pkey)) {
358 return -1;
359 }
360
361 if ((ctx = EVP_PKEY_CTX_new(pkey, NULL)) == NULL) {
362 return -1;
363 }
364
365 do {
366 if ((res = EVP_PKEY_sign_init(ctx)) <= 0) {
367 break;
368 }
369 if ((res = EVP_PKEY_CTX_set_rsa_padding(ctx, padding)) <= 0) {
370 break;
371 }
372 if ((res = EVP_PKEY_CTX_set_signature_md(ctx, EVP_sha1())) <= 0) {
373 break;
374 }
375 _siglen = *siglen;
376 if ((res = EVP_PKEY_sign(ctx, sig, &_siglen, in, inlen)) <= 0) {
377 break;
378 }
379 *siglen = _siglen;
380 } while (0);
381
382 EVP_PKEY_CTX_free(ctx);
383 return res;
384}

References in, and NULL.

Referenced by ast_sign_bin().

◆ evp_pkey_verify()

static int evp_pkey_verify ( EVP_PKEY *  pkey,
const unsigned char *  in,
unsigned  inlen,
const unsigned char *  sig,
unsigned  siglen,
unsigned  padding 
)
static

Definition at line 598 of file res_crypto.c.

599{
600 EVP_PKEY_CTX *ctx = NULL;
601 int res = -1;
602
603 if (siglen < EVP_PKEY_size(pkey)) {
604 return -1;
605 }
606
607 if ((ctx = EVP_PKEY_CTX_new(pkey, NULL)) == NULL) {
608 return -1;
609 }
610
611 do {
612 if ((res = EVP_PKEY_verify_init(ctx)) <= 0) {
613 break;
614 }
615 if ((res = EVP_PKEY_CTX_set_rsa_padding(ctx, padding)) <= 0) {
616 break;
617 }
618 if ((res = EVP_PKEY_CTX_set_signature_md(ctx, EVP_sha1())) <= 0) {
619 break;
620 }
621 if ((res = EVP_PKEY_verify(ctx, sig, siglen, in, inlen)) <= 0) {
622 break;
623 }
624 } while (0);
625
626 EVP_PKEY_CTX_free(ctx);
627 return res;
628}

References in, NULL, and ast_key::pkey.

Referenced by ast_check_signature_bin().

◆ handle_cli_keys_init()

static char * handle_cli_keys_init ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

initialize all RSA keys

Parameters
eCLI command
cmd
alist of CLI arguments
Return values
CLI_SUCCESS

Definition at line 916 of file res_crypto.c.

917{
918 struct ast_key *key;
919 int ign;
920 char *kn, tmp[256] = "";
921
922 switch (cmd) {
923 case CLI_INIT:
924 e->command = "keys init";
925 e->usage =
926 "Usage: keys init\n"
927 " Initializes private keys (by reading in pass code from\n"
928 " the user)\n";
929 return NULL;
930 case CLI_GENERATE:
931 return NULL;
932 }
933
934 if (a->argc != 2) {
935 return CLI_SHOWUSAGE;
936 }
937
940 /* Reload keys that need pass codes now */
941 if (key->ktype & KEY_NEEDS_PASSCODE) {
942 kn = key->fn + strlen(ast_config_AST_KEY_DIR) + 1;
943 ast_copy_string(tmp, kn, sizeof(tmp));
944 try_load_key(ast_config_AST_KEY_DIR, tmp, a->fd, a->fd, &ign);
945 }
946 }
949
950 return CLI_SUCCESS;
951}
static int tmp()
Definition: bt_open.c:389
#define CLI_SHOWUSAGE
Definition: cli.h:45
#define CLI_SUCCESS
Definition: cli.h:44
@ CLI_INIT
Definition: cli.h:152
@ CLI_GENERATE
Definition: cli.h:153
#define KEY_NEEDS_PASSCODE
Definition: res_crypto.c:73
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:425
char * command
Definition: cli.h:186
const char * usage
Definition: cli.h:177
char fn[256]
Definition: res_crypto.c:84
static struct test_val a

References a, 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_key::fn, KEY_NEEDS_PASSCODE, ast_key::ktype, NULL, tmp(), try_load_key(), and ast_cli_entry::usage.

◆ handle_cli_keys_show()

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
eCLI command
cmd
alist of CLI arguments
Return values
CLI_SUCCESS

Definition at line 870 of file res_crypto.c.

871{
872#define FORMAT "%-18s %-8s %-16s %-33s\n"
873
874 struct ast_key *key;
875 char sum[MD5_DIGEST_LENGTH * 2 + 1];
876 int count_keys = 0;
877
878 switch (cmd) {
879 case CLI_INIT:
880 e->command = "keys show";
881 e->usage =
882 "Usage: keys show\n"
883 " Displays information about RSA keys known by Asterisk\n";
884 return NULL;
885 case CLI_GENERATE:
886 return NULL;
887 }
888
889 ast_cli(a->fd, FORMAT, "Key Name", "Type", "Status", "Sum");
890 ast_cli(a->fd, FORMAT, "------------------", "--------", "----------------", "--------------------------------");
891
893 AST_RWLIST_TRAVERSE(&keys, key, list) {
894 md52sum(sum, key->digest);
895 ast_cli(a->fd, FORMAT, key->name,
896 (key->ktype & 0xf) == AST_KEY_PUBLIC ? "PUBLIC" : "PRIVATE",
897 key->ktype & KEY_NEEDS_PASSCODE ? "[Needs Passcode]" : "[Loaded]", sum);
898 count_keys++;
899 }
901
902 ast_cli(a->fd, "\n%d known RSA keys.\n", count_keys);
903
904 return CLI_SUCCESS;
905
906#undef FORMAT
907}
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
static void md52sum(char *sum, unsigned char *md5)
Definition: res_crypto.c:855
#define FORMAT
unsigned char digest[MD5_DIGEST_LENGTH]
Definition: res_crypto.c:96

References a, 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, FORMAT, KEY_NEEDS_PASSCODE, ast_key::ktype, md52sum(), ast_key::name, NULL, and ast_cli_entry::usage.

◆ load_module()

static int load_module ( void  )
static

Definition at line 971 of file res_crypto.c.

972{
973 crypto_init();
974 if (ast_opt_init_keys) {
975 crypto_load(STDIN_FILENO, STDOUT_FILENO);
976 } else {
977 crypto_load(-1, -1);
978 }
979
981}
@ AST_MODULE_LOAD_SUCCESS
Definition: module.h:70
#define ast_opt_init_keys
Definition: options.h:113
static int crypto_init(void)
initialise the res_crypto module
Definition: res_crypto.c:959

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

◆ md52sum()

static void md52sum ( char *  sum,
unsigned char *  md5 
)
static

Definition at line 855 of file res_crypto.c.

856{
857 int x;
858 for (x = 0; x < MD5_DIGEST_LENGTH; x++) {
859 sum += sprintf(sum, "%02hhx", *(md5++));
860 }
861}
static int md5(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
Definition: func_md5.c:52

References md5().

Referenced by handle_cli_keys_show().

◆ pw_cb()

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

113{
114 struct ast_key *key = (struct ast_key *)userdata;
115 char prompt[256];
116 int tmp;
117 int res;
118
119 if (key->infd < 0) {
120 /* Note that we were at least called */
121 key->infd = -2;
122 return -1;
123 }
124
125 snprintf(prompt, sizeof(prompt), ">>>> passcode for %s key '%s': ",
126 key->ktype == AST_KEY_PRIVATE ? "PRIVATE" : "PUBLIC", key->name);
127 if (write(key->outfd, prompt, strlen(prompt)) < 0) {
128 ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno));
129 key->infd = -2;
130 return -1;
131 }
132 tmp = ast_hide_password(key->infd);
133 memset(buf, 0, size);
134 res = read(key->infd, buf, size);
135 if (res == -1) {
136 ast_log(LOG_WARNING, "read() failed: %s\n", strerror(errno));
137 }
138 ast_restore_tty(key->infd, tmp);
139 if (buf[strlen(buf) -1] == '\n') {
140 buf[strlen(buf) - 1] = '\0';
141 }
142 return strlen(buf);
143}
static struct ast_str * prompt
Definition: asterisk.c:2780
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
int ast_hide_password(int fd)
Hide password.
Definition: io.c:337
int ast_restore_tty(int fd, int oldstatus)
Restores TTY mode.
Definition: io.c:356
int errno
int infd
Definition: res_crypto.c:92
int outfd
Definition: res_crypto.c:94

References ast_hide_password(), AST_KEY_PRIVATE, ast_log, ast_restore_tty(), buf, errno, ast_key::infd, ast_key::ktype, LOG_WARNING, ast_key::name, ast_key::outfd, prompt, and tmp().

Referenced by try_load_key().

◆ reload()

static int reload ( void  )
static

Definition at line 965 of file res_crypto.c.

966{
967 crypto_load(-1, -1);
968 return 0;
969}

References crypto_load().

◆ try_load_key()

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
dirdirectory string
fnamename of file
ifdincoming file descriptor
ofdoutgoing file descriptor
not2
Returns
key on success.
Return values
NULLon failure.

Definition at line 175 of file res_crypto.c.

176{
177 int n, ktype = 0, found = 0;
178 const char *c = NULL;
179 char ffname[256];
180 unsigned char digest[MD5_DIGEST_LENGTH];
181 unsigned digestlen;
182 FILE *f;
183 EVP_MD_CTX *ctx = NULL;
184 struct ast_key *key;
185 static int notice = 0;
186 struct stat st;
187 size_t fnamelen = strlen(fname);
188
189 /* Make sure its name is a public or private key */
190 if (fnamelen > 4 && !strcmp((c = &fname[fnamelen - 4]), ".pub")) {
191 ktype = AST_KEY_PUBLIC;
192 } else if (fnamelen > 4 && !strcmp((c = &fname[fnamelen - 4]), ".key")) {
193 ktype = AST_KEY_PRIVATE;
194 } else {
195 return NULL;
196 }
197
198 /* Get actual filename */
199 n = snprintf(ffname, sizeof(ffname), "%s/%s", dir, fname);
200 if (n >= sizeof(ffname)) {
202 "Key filenames can be up to %zu bytes long, but the filename for the"
203 " key we are currently trying to load (%s/%s) is %d bytes long.",
204 sizeof(ffname) - 1, dir, fname, n);
205 return NULL;
206 }
207
208 /* Open file */
209 if (!(f = fopen(ffname, "r"))) {
210 ast_log(LOG_WARNING, "Unable to open key file %s: %s\n", ffname, strerror(errno));
211 return NULL;
212 }
213
214 n = fstat(fileno(f), &st);
215 if (n != 0) {
216 ast_log(LOG_ERROR, "Unable to stat key file: %s: %s\n", ffname, strerror(errno));
217 fclose(f);
218 return NULL;
219 }
220
221 if (!S_ISREG(st.st_mode)) {
222 ast_log(LOG_ERROR, "Key file is not a regular file: %s\n", ffname);
223 fclose(f);
224 return NULL;
225 }
226
227 /* FILE_MODE_BITS is a bitwise OR of all possible file mode bits encoded in
228 * the `st_mode` member of `struct stat`. For POSIX compatible systems this
229 * will be 07777. */
230#define FILE_MODE_BITS (S_ISUID|S_ISGID|S_ISVTX|S_IRWXU|S_IRWXG|S_IRWXO)
231
232 /* only user read or read/write modes allowed */
233 if (ktype == AST_KEY_PRIVATE &&
234 ((st.st_mode & FILE_MODE_BITS) & ~(S_IRUSR | S_IWUSR)) != 0) {
235 ast_log(LOG_ERROR, "Private key file has bad permissions: %s: %#4o\n", ffname, st.st_mode & FILE_MODE_BITS);
236 fclose(f);
237 return NULL;
238 }
239
240 ctx = EVP_MD_CTX_create();
241 if (ctx == NULL) {
242 ast_log(LOG_ERROR, "Out of memory\n");
243 fclose(f);
244 return NULL;
245 }
246 EVP_DigestInit(ctx, EVP_md5());
247
248 while (!feof(f)) {
249 /* Calculate a "whatever" quality md5sum of the key */
250 char buf[256] = "";
251 if (!fgets(buf, sizeof(buf), f)) {
252 continue;
253 }
254 if (!feof(f)) {
255 EVP_DigestUpdate(ctx, (unsigned char *)buf, strlen(buf));
256 }
257 }
258 EVP_DigestFinal(ctx, digest, &digestlen);
259 EVP_MD_CTX_destroy(ctx);
260
261 /* Look for an existing key */
262 AST_RWLIST_TRAVERSE(&keys, key, list) {
263 if (!strcasecmp(key->fn, ffname)) {
264 break;
265 }
266 }
267
268 if (key) {
269 /* If the MD5 sum is the same, and it isn't awaiting a passcode
270 then this is far enough */
271 if (!memcmp(digest, key->digest, sizeof(digest)) &&
272 !(key->ktype & KEY_NEEDS_PASSCODE)) {
273 fclose(f);
274 key->delme = 0;
275 return NULL;
276 } else {
277 /* Preserve keytype */
278 ktype = key->ktype;
279 /* Recycle the same structure */
280 found++;
281 }
282 }
283
284 if (!key) {
285 if (!(key = ast_calloc(1, sizeof(*key)))) {
286 fclose(f);
287 return NULL;
288 }
289 }
290 /* First the filename */
291 ast_copy_string(key->fn, ffname, sizeof(key->fn));
292 /* Then the name minus the suffix */
293 snprintf(key->name, sizeof(key->name), "%.*s", (int)(c - fname), fname);
294 key->ktype = ktype;
295 /* Yes, assume we're going to be deleted */
296 key->delme = 1;
297 /* Keep the key type */
298 memcpy(key->digest, digest, sizeof(key->digest));
299 /* Can I/O takes the FD we're given */
300 key->infd = ifd;
301 key->outfd = ofd;
302 /* Reset the file back to the beginning */
303 rewind(f);
304 /* Now load the key with the right method */
305 if (ktype == AST_KEY_PUBLIC) {
306 PEM_read_PUBKEY(f, &key->pkey, pw_cb, key);
307 } else {
308 PEM_read_PrivateKey(f, &key->pkey, pw_cb, key);
309 }
310 fclose(f);
311 if (key->pkey) {
312 if (EVP_PKEY_size(key->pkey) == (AST_CRYPTO_RSA_KEY_BITS / 8)) {
313 /* Key loaded okay */
314 key->ktype &= ~KEY_NEEDS_PASSCODE;
315 ast_verb(3, "Loaded %s key '%s'\n", key->ktype == AST_KEY_PUBLIC ? "PUBLIC" : "PRIVATE", key->name);
316 ast_debug(1, "Key '%s' loaded OK\n", key->name);
317 key->delme = 0;
318 } else {
319 ast_log(LOG_NOTICE, "Key '%s' is not expected size.\n", key->name);
320 }
321 } else if (key->infd != -2) {
322 ast_log(LOG_WARNING, "Key load %s '%s' failed\n", key->ktype == AST_KEY_PUBLIC ? "PUBLIC" : "PRIVATE", key->name);
323 if (ofd > -1) {
324 ERR_print_errors_fp(stderr);
325 } else {
326 ERR_print_errors_fp(stderr);
327 }
328 } else {
329 ast_log(LOG_NOTICE, "Key '%s' needs passcode.\n", key->name);
331 if (!notice) {
332 if (!ast_opt_init_keys) {
333 ast_log(LOG_NOTICE, "Add the '-i' flag to the asterisk command line if you want to automatically initialize passcodes at launch.\n");
334 }
335 notice++;
336 }
337 /* Keep it anyway */
338 key->delme = 0;
339 /* Print final notice about "keys init" when done */
340 *not2 = 1;
341 }
342
343 /* If this is a new key add it to the list */
344 if (!found) {
345 AST_RWLIST_INSERT_TAIL(&keys, key, list);
346 }
347
348 return key;
349}
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:202
#define AST_CRYPTO_RSA_KEY_BITS
Definition: crypto.h:36
#define ast_verb(level,...)
#define AST_RWLIST_INSERT_TAIL
Definition: linkedlists.h:741
#define FILE_MODE_BITS
static int pw_cb(char *buf, int size, int rwflag, void *userdata)
setting of priv key
Definition: res_crypto.c:112
static struct test_val c

References ast_calloc, ast_copy_string(), AST_CRYPTO_RSA_KEY_BITS, ast_debug, AST_KEY_PRIVATE, AST_KEY_PUBLIC, ast_log, ast_opt_init_keys, AST_RWLIST_INSERT_TAIL, AST_RWLIST_TRAVERSE, ast_verb, buf, c, ast_key::delme, ast_key::digest, errno, FILE_MODE_BITS, ast_key::fn, ast_key::infd, KEY_NEEDS_PASSCODE, ast_key::ktype, LOG_ERROR, LOG_NOTICE, LOG_WARNING, ast_key::name, NULL, ast_key::outfd, ast_key::pkey, and pw_cb().

Referenced by crypto_load_cb(), and handle_cli_keys_init().

◆ unload_module()

static int unload_module ( void  )
static

Since we don't have a config file, we could move up to REALTIME_DEPEND, if necessary

Definition at line 983 of file res_crypto.c.

References ARRAY_LEN, ast_cli_unregister_multiple(), and cli_crypto.

Variable Documentation

◆ __mod_info

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, .support_level = AST_MODULE_SUPPORT_CORE, .load = load_module, .unload = unload_module, .reload = reload, .load_pri = AST_MODPRI_CHANNEL_DEPEND, }
static

Definition at line 996 of file res_crypto.c.

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

Definition at line 996 of file res_crypto.c.

◆ cli_crypto

struct ast_cli_entry cli_crypto[]
static
Initial value:
= {
{ .handler = handle_cli_keys_show , .summary = "Displays RSA key information" ,},
{ .handler = handle_cli_keys_init , .summary = "Initialize RSA key passcodes" ,}
}
static char * handle_cli_keys_init(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
initialize all RSA keys
Definition: res_crypto.c:916
static char * handle_cli_keys_show(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
show the list of RSA keys
Definition: res_crypto.c:870

Definition at line 953 of file res_crypto.c.

Referenced by crypto_init(), and unload_module().

◆ keys

struct keys keys = { .first = NULL, .last = NULL, .lock = { PTHREAD_RWLOCK_INITIALIZER , NULL, {1, 0} } , }
static

Referenced by store_odbc().