Wed Jan 8 2020 09:49:50

Asterisk developer's documentation


res_crypto.c
Go to the documentation of this file.
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 1999 - 2006, Digium, Inc.
5  *
6  * Mark Spencer <markster@digium.com>
7  *
8  * See http://www.asterisk.org for more information about
9  * the Asterisk project. Please do not directly contact
10  * any of the maintainers of this project for assistance;
11  * the project provides a web site, mailing lists and IRC
12  * channels for your use.
13  *
14  * This program is free software, distributed under the terms of
15  * the GNU General Public License Version 2. See the LICENSE file
16  * at the top of the source tree.
17  */
18 
19 /*! \file
20  *
21  * \brief Provide Cryptographic Signature capability
22  *
23  * \author Mark Spencer <markster@digium.com>
24  *
25  * \extref Uses the OpenSSL library, available at
26  * http://www.openssl.org/
27  */
28 
29 /*** MODULEINFO
30  <depend>openssl</depend>
31  <support_level>core</support_level>
32  ***/
33 
34 #include "asterisk.h"
35 
36 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 413586 $")
37 
38 #include "asterisk/paths.h" /* use ast_config_AST_KEY_DIR */
39 #include <openssl/ssl.h>
40 #include <openssl/err.h>
41 #include <openssl/aes.h>
42 #include <dirent.h>
43 
44 #include "asterisk/module.h"
45 #include "asterisk/md5.h"
46 #include "asterisk/cli.h"
47 #include "asterisk/io.h"
48 #include "asterisk/lock.h"
49 #include "asterisk/utils.h"
50 
51 #define AST_API_MODULE
52 #include "asterisk/crypto.h"
53 
54 /*
55  * Asterisk uses RSA keys with SHA-1 message digests for its
56  * digital signatures. The choice of RSA is due to its higher
57  * throughput on verification, and the choice of SHA-1 based
58  * on the recently discovered collisions in MD5's compression
59  * algorithm and recommendations of avoiding MD5 in new schemes
60  * from various industry experts.
61  *
62  * We use OpenSSL to provide our crypto routines, although we never
63  * actually use full-up SSL
64  *
65  */
66 
67 #define KEY_NEEDS_PASSCODE (1 << 16)
68 
69 struct ast_key {
70  /*! Name of entity */
71  char name[80];
72  /*! File name */
73  char fn[256];
74  /*! Key type (AST_KEY_PUB or AST_KEY_PRIV, along with flags from above) */
75  int ktype;
76  /*! RSA structure (if successfully loaded) */
77  RSA *rsa;
78  /*! Whether we should be deleted */
79  int delme;
80  /*! FD for input (or -1 if no input allowed, or -2 if we needed input) */
81  int infd;
82  /*! FD for output */
83  int outfd;
84  /*! Last MD5 Digest */
85  unsigned char digest[16];
87 };
88 
90 
91 /*!
92  * \brief setting of priv key
93  * \param buf
94  * \param size
95  * \param rwflag
96  * \param userdata
97  * \return length of string,-1 on failure
98 */
99 static int pw_cb(char *buf, int size, int rwflag, void *userdata)
100 {
101  struct ast_key *key = (struct ast_key *)userdata;
102  char prompt[256];
103  int tmp;
104  int res;
105 
106  if (key->infd < 0) {
107  /* Note that we were at least called */
108  key->infd = -2;
109  return -1;
110  }
111 
112  snprintf(prompt, sizeof(prompt), ">>>> passcode for %s key '%s': ",
113  key->ktype == AST_KEY_PRIVATE ? "PRIVATE" : "PUBLIC", key->name);
114  if (write(key->outfd, prompt, strlen(prompt)) < 0) {
115  ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno));
116  key->infd = -2;
117  return -1;
118  }
119  tmp = ast_hide_password(key->infd);
120  memset(buf, 0, size);
121  res = read(key->infd, buf, size);
122  if (res == -1) {
123  ast_log(LOG_WARNING, "read() failed: %s\n", strerror(errno));
124  }
125  ast_restore_tty(key->infd, tmp);
126  if (buf[strlen(buf) -1] == '\n') {
127  buf[strlen(buf) - 1] = '\0';
128  }
129  return strlen(buf);
130 }
131 
132 /*!
133  * \brief return the ast_key structure for name
134  * \see ast_key_get
135 */
136 struct ast_key * AST_OPTIONAL_API_NAME(ast_key_get)(const char *kname, int ktype)
137 {
138  struct ast_key *key;
139 
141  AST_RWLIST_TRAVERSE(&keys, key, list) {
142  if (!strcmp(kname, key->name) &&
143  (ktype == key->ktype)) {
144  break;
145  }
146  }
148 
149  return key;
150 }
151 
152 /*!
153  * \brief load RSA key from file
154  * \param dir directory string
155  * \param fname name of file
156  * \param ifd incoming file descriptor
157  * \param ofd outgoing file descriptor
158  * \param not2
159  * \retval key on success.
160  * \retval NULL on failure.
161 */
162 static struct ast_key *try_load_key(const char *dir, const char *fname, int ifd, int ofd, int *not2)
163 {
164  int ktype = 0, found = 0;
165  char *c = NULL, ffname[256];
166  unsigned char digest[16];
167  FILE *f;
168  struct MD5Context md5;
169  struct ast_key *key;
170  static int notice = 0;
171 
172  /* Make sure its name is a public or private key */
173  if ((c = strstr(fname, ".pub")) && !strcmp(c, ".pub")) {
174  ktype = AST_KEY_PUBLIC;
175  } else if ((c = strstr(fname, ".key")) && !strcmp(c, ".key")) {
176  ktype = AST_KEY_PRIVATE;
177  } else {
178  return NULL;
179  }
180 
181  /* Get actual filename */
182  snprintf(ffname, sizeof(ffname), "%s/%s", dir, fname);
183 
184  /* Open file */
185  if (!(f = fopen(ffname, "r"))) {
186  ast_log(LOG_WARNING, "Unable to open key file %s: %s\n", ffname, strerror(errno));
187  return NULL;
188  }
189 
190  MD5Init(&md5);
191  while (!feof(f)) {
192  /* Calculate a "whatever" quality md5sum of the key */
193  char buf[256] = "";
194  if (!fgets(buf, sizeof(buf), f)) {
195  continue;
196  }
197  if (!feof(f)) {
198  MD5Update(&md5, (unsigned char *) buf, strlen(buf));
199  }
200  }
201  MD5Final(digest, &md5);
202 
203  /* Look for an existing key */
204  AST_RWLIST_TRAVERSE(&keys, key, list) {
205  if (!strcasecmp(key->fn, ffname)) {
206  break;
207  }
208  }
209 
210  if (key) {
211  /* If the MD5 sum is the same, and it isn't awaiting a passcode
212  then this is far enough */
213  if (!memcmp(digest, key->digest, 16) &&
214  !(key->ktype & KEY_NEEDS_PASSCODE)) {
215  fclose(f);
216  key->delme = 0;
217  return NULL;
218  } else {
219  /* Preserve keytype */
220  ktype = key->ktype;
221  /* Recycle the same structure */
222  found++;
223  }
224  }
225 
226  /* Make fname just be the normal name now */
227  *c = '\0';
228  if (!key) {
229  if (!(key = ast_calloc(1, sizeof(*key)))) {
230  fclose(f);
231  return NULL;
232  }
233  }
234  /* First the filename */
235  ast_copy_string(key->fn, ffname, sizeof(key->fn));
236  /* Then the name */
237  ast_copy_string(key->name, fname, sizeof(key->name));
238  key->ktype = ktype;
239  /* Yes, assume we're going to be deleted */
240  key->delme = 1;
241  /* Keep the key type */
242  memcpy(key->digest, digest, 16);
243  /* Can I/O takes the FD we're given */
244  key->infd = ifd;
245  key->outfd = ofd;
246  /* Reset the file back to the beginning */
247  rewind(f);
248  /* Now load the key with the right method */
249  if (ktype == AST_KEY_PUBLIC) {
250  key->rsa = PEM_read_RSA_PUBKEY(f, NULL, pw_cb, key);
251  } else {
252  key->rsa = PEM_read_RSAPrivateKey(f, NULL, pw_cb, key);
253  }
254  fclose(f);
255  if (key->rsa) {
256  if (RSA_size(key->rsa) == 128) {
257  /* Key loaded okay */
258  key->ktype &= ~KEY_NEEDS_PASSCODE;
259  ast_verb(3, "Loaded %s key '%s'\n", key->ktype == AST_KEY_PUBLIC ? "PUBLIC" : "PRIVATE", key->name);
260  ast_debug(1, "Key '%s' loaded OK\n", key->name);
261  key->delme = 0;
262  } else {
263  ast_log(LOG_NOTICE, "Key '%s' is not expected size.\n", key->name);
264  }
265  } else if (key->infd != -2) {
266  ast_log(LOG_WARNING, "Key load %s '%s' failed\n",key->ktype == AST_KEY_PUBLIC ? "PUBLIC" : "PRIVATE", key->name);
267  if (ofd > -1) {
268  ERR_print_errors_fp(stderr);
269  } else {
270  ERR_print_errors_fp(stderr);
271  }
272  } else {
273  ast_log(LOG_NOTICE, "Key '%s' needs passcode.\n", key->name);
274  key->ktype |= KEY_NEEDS_PASSCODE;
275  if (!notice) {
276  if (!ast_opt_init_keys) {
277  ast_log(LOG_NOTICE, "Add the '-i' flag to the asterisk command line if you want to automatically initialize passcodes at launch.\n");
278  }
279  notice++;
280  }
281  /* Keep it anyway */
282  key->delme = 0;
283  /* Print final notice about "keys init" when done */
284  *not2 = 1;
285  }
286 
287  /* If this is a new key add it to the list */
288  if (!found) {
289  AST_RWLIST_INSERT_TAIL(&keys, key, list);
290  }
291 
292  return key;
293 }
294 
295 /*!
296  * \brief signs outgoing message with public key
297  * \see ast_sign_bin
298 */
299 int AST_OPTIONAL_API_NAME(ast_sign_bin)(struct ast_key *key, const char *msg, int msglen, unsigned char *dsig)
300 {
301  unsigned char digest[20];
302  unsigned int siglen = 128;
303  int res;
304 
305  if (key->ktype != AST_KEY_PRIVATE) {
306  ast_log(LOG_WARNING, "Cannot sign with a public key\n");
307  return -1;
308  }
309 
310  /* Calculate digest of message */
311  SHA1((unsigned char *)msg, msglen, digest);
312 
313  /* Verify signature */
314  if (!(res = RSA_sign(NID_sha1, digest, sizeof(digest), dsig, &siglen, key->rsa))) {
315  ast_log(LOG_WARNING, "RSA Signature (key %s) failed\n", key->name);
316  return -1;
317  }
318 
319  if (siglen != 128) {
320  ast_log(LOG_WARNING, "Unexpected signature length %d, expecting %d\n", (int)siglen, (int)128);
321  return -1;
322  }
323 
324  return 0;
325 }
326 
327 /*!
328  * \brief decrypt a message
329  * \see ast_decrypt_bin
330 */
331 int AST_OPTIONAL_API_NAME(ast_decrypt_bin)(unsigned char *dst, const unsigned char *src, int srclen, struct ast_key *key)
332 {
333  int res, pos = 0;
334 
335  if (key->ktype != AST_KEY_PRIVATE) {
336  ast_log(LOG_WARNING, "Cannot decrypt with a public key\n");
337  return -1;
338  }
339 
340  if (srclen % 128) {
341  ast_log(LOG_NOTICE, "Tried to decrypt something not a multiple of 128 bytes\n");
342  return -1;
343  }
344 
345  while (srclen) {
346  /* Process chunks 128 bytes at a time */
347  if ((res = RSA_private_decrypt(128, src, dst, key->rsa, RSA_PKCS1_OAEP_PADDING)) < 0) {
348  return -1;
349  }
350  pos += res;
351  src += 128;
352  srclen -= 128;
353  dst += res;
354  }
355 
356  return pos;
357 }
358 
359 /*!
360  * \brief encrypt a message
361  * \see ast_encrypt_bin
362 */
363 int AST_OPTIONAL_API_NAME(ast_encrypt_bin)(unsigned char *dst, const unsigned char *src, int srclen, struct ast_key *key)
364 {
365  int res, bytes, pos = 0;
366 
367  if (key->ktype != AST_KEY_PUBLIC) {
368  ast_log(LOG_WARNING, "Cannot encrypt with a private key\n");
369  return -1;
370  }
371 
372  while (srclen) {
373  bytes = srclen;
374  if (bytes > 128 - 41) {
375  bytes = 128 - 41;
376  }
377  /* Process chunks 128-41 bytes at a time */
378  if ((res = RSA_public_encrypt(bytes, src, dst, key->rsa, RSA_PKCS1_OAEP_PADDING)) != 128) {
379  ast_log(LOG_NOTICE, "How odd, encrypted size is %d\n", res);
380  return -1;
381  }
382  src += bytes;
383  srclen -= bytes;
384  pos += res;
385  dst += res;
386  }
387  return pos;
388 }
389 
390 /*!
391  * \brief wrapper for __ast_sign_bin then base64 encode it
392  * \see ast_sign
393 */
394 int AST_OPTIONAL_API_NAME(ast_sign)(struct ast_key *key, char *msg, char *sig)
395 {
396  unsigned char dsig[128];
397  int siglen = sizeof(dsig), res;
398 
399  if (!(res = ast_sign_bin(key, msg, strlen(msg), dsig))) {
400  /* Success -- encode (256 bytes max as documented) */
401  ast_base64encode(sig, dsig, siglen, 256);
402  }
403 
404  return res;
405 }
406 
407 /*!
408  * \brief check signature of a message
409  * \see ast_check_signature_bin
410 */
411 int AST_OPTIONAL_API_NAME(ast_check_signature_bin)(struct ast_key *key, const char *msg, int msglen, const unsigned char *dsig)
412 {
413  unsigned char digest[20];
414  int res;
415 
416  if (key->ktype != AST_KEY_PUBLIC) {
417  /* Okay, so of course you really *can* but for our purposes
418  we're going to say you can't */
419  ast_log(LOG_WARNING, "Cannot check message signature with a private key\n");
420  return -1;
421  }
422 
423  /* Calculate digest of message */
424  SHA1((unsigned char *)msg, msglen, digest);
425 
426  /* Verify signature */
427  if (!(res = RSA_verify(NID_sha1, digest, sizeof(digest), (unsigned char *)dsig, 128, key->rsa))) {
428  ast_debug(1, "Key failed verification: %s\n", key->name);
429  return -1;
430  }
431 
432  /* Pass */
433  return 0;
434 }
435 
436 /*!
437  * \brief base64 decode then sent to __ast_check_signature_bin
438  * \see ast_check_signature
439 */
440 int AST_OPTIONAL_API_NAME(ast_check_signature)(struct ast_key *key, const char *msg, const char *sig)
441 {
442  unsigned char dsig[128];
443  int res;
444 
445  /* Decode signature */
446  if ((res = ast_base64decode(dsig, sig, sizeof(dsig))) != sizeof(dsig)) {
447  ast_log(LOG_WARNING, "Signature improper length (expect %d, got %d)\n", (int)sizeof(dsig), (int)res);
448  return -1;
449  }
450 
451  res = ast_check_signature_bin(key, msg, strlen(msg), dsig);
452 
453  return res;
454 }
455 
457 {
458  return 1;
459 }
460 
462 {
463  return AES_set_encrypt_key(key, 128, ctx);
464 }
465 
467 {
468  return AES_set_decrypt_key(key, 128, ctx);
469 }
470 
471 void AST_OPTIONAL_API_NAME(ast_aes_encrypt)(const unsigned char *in, unsigned char *out, const ast_aes_encrypt_key *ctx)
472 {
473  return AES_encrypt(in, out, ctx);
474 }
475 
476 void AST_OPTIONAL_API_NAME(ast_aes_decrypt)(const unsigned char *in, unsigned char *out, const ast_aes_decrypt_key *ctx)
477 {
478  return AES_decrypt(in, out, ctx);
479 }
480 
481 /*!
482  * \brief refresh RSA keys from file
483  * \param ifd file descriptor
484  * \param ofd file descriptor
485  * \return void
486 */
487 static void crypto_load(int ifd, int ofd)
488 {
489  struct ast_key *key;
490  DIR *dir = NULL;
491  struct dirent *ent;
492  int note = 0;
493 
495 
496  /* Mark all keys for deletion */
497  AST_RWLIST_TRAVERSE(&keys, key, list) {
498  key->delme = 1;
499  }
500 
501  /* Load new keys */
502  if ((dir = opendir(ast_config_AST_KEY_DIR))) {
503  while ((ent = readdir(dir))) {
504  try_load_key(ast_config_AST_KEY_DIR, ent->d_name, ifd, ofd, &note);
505  }
506  closedir(dir);
507  } else {
508  ast_log(LOG_WARNING, "Unable to open key directory '%s'\n", ast_config_AST_KEY_DIR);
509  }
510 
511  if (note) {
512  ast_log(LOG_NOTICE, "Please run the command 'keys init' to enter the passcodes for the keys\n");
513  }
514 
515  /* Delete any keys that are no longer present */
516  AST_RWLIST_TRAVERSE_SAFE_BEGIN(&keys, key, list) {
517  if (key->delme) {
518  ast_debug(1, "Deleting key %s type %d\n", key->name, key->ktype);
520  if (key->rsa) {
521  RSA_free(key->rsa);
522  }
523  ast_free(key);
524  }
525  }
527 
529 }
530 
531 static void md52sum(char *sum, unsigned char *md5)
532 {
533  int x;
534  for (x = 0; x < 16; x++) {
535  sum += sprintf(sum, "%02x", (unsigned)*(md5++));
536  }
537 }
538 
539 /*!
540  * \brief show the list of RSA keys
541  * \param e CLI command
542  * \param cmd
543  * \param a list of CLI arguments
544  * \return CLI_SUCCESS
545 */
546 static char *handle_cli_keys_show(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
547 {
548 #define FORMAT "%-18s %-8s %-16s %-33s\n"
549 
550  struct ast_key *key;
551  char sum[16 * 2 + 1];
552  int count_keys = 0;
553 
554  switch (cmd) {
555  case CLI_INIT:
556  e->command = "keys show";
557  e->usage =
558  "Usage: keys show\n"
559  " Displays information about RSA keys known by Asterisk\n";
560  return NULL;
561  case CLI_GENERATE:
562  return NULL;
563  }
564 
565  ast_cli(a->fd, FORMAT, "Key Name", "Type", "Status", "Sum");
566  ast_cli(a->fd, FORMAT, "------------------", "--------", "----------------", "--------------------------------");
567 
569  AST_RWLIST_TRAVERSE(&keys, key, list) {
570  md52sum(sum, key->digest);
571  ast_cli(a->fd, FORMAT, key->name,
572  (key->ktype & 0xf) == AST_KEY_PUBLIC ? "PUBLIC" : "PRIVATE",
573  key->ktype & KEY_NEEDS_PASSCODE ? "[Needs Passcode]" : "[Loaded]", sum);
574  count_keys++;
575  }
577 
578  ast_cli(a->fd, "\n%d known RSA keys.\n", count_keys);
579 
580  return CLI_SUCCESS;
581 
582 #undef FORMAT
583 }
584 
585 /*!
586  * \brief initialize all RSA keys
587  * \param e CLI command
588  * \param cmd
589  * \param a list of CLI arguments
590  * \return CLI_SUCCESS
591 */
592 static char *handle_cli_keys_init(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
593 {
594  struct ast_key *key;
595  int ign;
596  char *kn, tmp[256] = "";
597 
598  switch (cmd) {
599  case CLI_INIT:
600  e->command = "keys init";
601  e->usage =
602  "Usage: keys init\n"
603  " Initializes private keys (by reading in pass code from\n"
604  " the user)\n";
605  return NULL;
606  case CLI_GENERATE:
607  return NULL;
608  }
609 
610  if (a->argc != 2) {
611  return CLI_SHOWUSAGE;
612  }
613 
615  AST_RWLIST_TRAVERSE_SAFE_BEGIN(&keys, key, list) {
616  /* Reload keys that need pass codes now */
617  if (key->ktype & KEY_NEEDS_PASSCODE) {
618  kn = key->fn + strlen(ast_config_AST_KEY_DIR) + 1;
619  ast_copy_string(tmp, kn, sizeof(tmp));
620  try_load_key(ast_config_AST_KEY_DIR, tmp, a->fd, a->fd, &ign);
621  }
622  }
625 
626  return CLI_SUCCESS;
627 }
628 
629 static struct ast_cli_entry cli_crypto[] = {
630  AST_CLI_DEFINE(handle_cli_keys_show, "Displays RSA key information"),
631  AST_CLI_DEFINE(handle_cli_keys_init, "Initialize RSA key passcodes")
632 };
633 
634 /*! \brief initialise the res_crypto module */
635 static int crypto_init(void)
636 {
638  return 0;
639 }
640 
641 static int reload(void)
642 {
643  crypto_load(-1, -1);
644  return 0;
645 }
646 
647 static int load_module(void)
648 {
649  crypto_init();
650  if (ast_opt_init_keys) {
651  crypto_load(STDIN_FILENO, STDOUT_FILENO);
652  } else {
653  crypto_load(-1, -1);
654  }
656 }
657 
658 static int unload_module(void)
659 {
660  /* Can't unload this once we're loaded */
661  return -1;
662 }
663 
664 /* needs usecount semantics defined */
666  .load = load_module,
667  .unload = unload_module,
668  .reload = reload,
669  .load_pri = AST_MODPRI_CHANNEL_DEPEND, /*!< Since we don't have a config file, we could move up to REALTIME_DEPEND, if necessary */
670  );
int ast_decrypt_bin(unsigned char *dst, const unsigned char *src, int srclen, struct ast_key *key)
Decrypt a message using a given private key.
Definition: res_crypto.c:331
const char * ast_config_AST_KEY_DIR
Definition: asterisk.c:265
static int load_module(void)
Definition: res_crypto.c:647
RSA * rsa
Definition: res_crypto.c:77
#define AST_CLI_DEFINE(fn, txt,...)
Definition: cli.h:191
Asterisk locking-related definitions:
Asterisk main include file. File version handling, generic pbx functions.
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
int ast_check_signature_bin(struct ast_key *key, const char *msg, int msglen, const unsigned char *sig)
Check the authenticity of a message signature using a given public key.
Definition: res_crypto.c:411
int ast_crypto_loaded(void)
Definition: res_crypto.c:456
#define AST_RWLIST_HEAD_STATIC(name, type)
Defines a structure to be used to hold a read/write list of specified type, statically initialized...
Definition: linkedlists.h:332
int ktype
Definition: res_crypto.c:75
int ast_aes_set_encrypt_key(const unsigned char *key, ast_aes_encrypt_key *ctx)
Set an encryption key.
Definition: res_crypto.c:461
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:162
#define AST_RWLIST_WRLOCK(head)
Write locks a list.
Definition: linkedlists.h:51
descriptor for a cli entry.
Definition: cli.h:165
const int argc
Definition: cli.h:154
#define LOG_WARNING
Definition: logger.h:144
int ast_hide_password(int fd)
Definition: io.c:332
Provide cryptographic signature routines.
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
void MD5Final(unsigned char digest[16], struct MD5Context *context)
Definition: md5.c:122
Definition: cli.h:146
#define FORMAT
#define AST_MODULE_INFO(keystr, flags_to_set, desc, fields...)
Definition: module.h:374
I/O Management (derived from Cheops-NG)
void ast_cli(int fd, const char *fmt,...)
Definition: cli.c:105
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:592
#define ast_opt_init_keys
Definition: options.h:109
#define ast_verb(level,...)
Definition: logger.h:243
void MD5Init(struct MD5Context *context)
Definition: md5.c:59
void ast_aes_decrypt(const unsigned char *in, unsigned char *out, const ast_aes_decrypt_key *ctx)
AES decrypt data.
Definition: res_crypto.c:476
static struct ast_cli_entry cli_crypto[]
Definition: res_crypto.c:629
Utility functions.
static int unload_module(void)
Definition: res_crypto.c:658
int ast_restore_tty(int fd, int oldstatus)
Restores TTY mode. Call with result from previous ast_hide_password.
Definition: io.c:351
int outfd
Definition: res_crypto.c:83
#define AST_RWLIST_RDLOCK(head)
Read locks a list.
Definition: linkedlists.h:77
AES_KEY ast_aes_encrypt_key
Definition: crypto.h:35
int ast_base64decode(unsigned char *dst, const char *src, int max)
Decode data from base64.
Definition: utils.c:279
void ast_aes_encrypt(const unsigned char *in, unsigned char *out, const ast_aes_encrypt_key *ctx)
AES encrypt data.
Definition: res_crypto.c:471
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
int ast_encrypt_bin(unsigned char *dst, const unsigned char *src, int srclen, struct ast_key *key)
Encrypt a message using a given private key.
Definition: res_crypto.c:363
int ast_sign_bin(struct ast_key *key, const char *msg, int msglen, unsigned char *sig)
Sign a message signature using a given private key.
Definition: res_crypto.c:299
static int reload(void)
Definition: res_crypto.c:641
const int fd
Definition: cli.h:153
#define AST_RWLIST_TRAVERSE
Definition: linkedlists.h:493
#define AST_RWLIST_REMOVE_CURRENT
Definition: linkedlists.h:565
#define AST_KEY_PRIVATE
Definition: crypto.h:43
#define AST_RWLIST_TRAVERSE_SAFE_BEGIN
Definition: linkedlists.h:542
void MD5Update(struct MD5Context *context, unsigned char const *buf, unsigned len)
Definition: md5.c:74
char name[80]
Definition: res_crypto.c:71
Definition: sha1.h:122
static int md5(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
Definition: func_md5.c:54
int ast_base64encode(char *dst, const unsigned char *src, int srclen, int max)
Encode data in base64.
Definition: utils.c:357
#define CLI_SHOWUSAGE
Definition: cli.h:44
int ast_aes_set_decrypt_key(const unsigned char *key, ast_aes_decrypt_key *ctx)
Set a decryption key.
Definition: res_crypto.c:466
unsigned char digest[16]
Definition: res_crypto.c:85
#define KEY_NEEDS_PASSCODE
Definition: res_crypto.c:67
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define LOG_NOTICE
Definition: logger.h:133
static void md52sum(char *sum, unsigned char *md5)
Definition: res_crypto.c:531
int ast_sign(struct ast_key *key, char *msg, char *sig)
Sign a message signature using a given private key.
Definition: res_crypto.c:394
int infd
Definition: res_crypto.c:81
int errno
char fn[256]
Definition: res_crypto.c:73
#define ast_free(a)
Definition: astmm.h:97
char * command
Definition: cli.h:180
AES_KEY ast_aes_decrypt_key
Definition: crypto.h:36
int delme
Definition: res_crypto.c:79
static struct ast_format f[]
Definition: format_g726.c:181
static void crypto_load(int ifd, int ofd)
refresh RSA keys from file
Definition: res_crypto.c:487
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:546
Definition: md5.h:26
#define AST_RWLIST_ENTRY
Definition: linkedlists.h:414
const char * usage
Definition: cli.h:171
#define CLI_SUCCESS
Definition: cli.h:43
#define AST_RWLIST_INSERT_TAIL
Definition: linkedlists.h:726
Standard Command Line Interface.
#define ast_calloc(a, b)
Definition: astmm.h:82
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
int ast_cli_register_multiple(struct ast_cli_entry *e, int len)
Register multiple commands.
Definition: cli.c:2167
int ast_check_signature(struct ast_key *key, const char *msg, const char *sig)
Check the authenticity of a message signature using a given public key.
Definition: res_crypto.c:440
#define AST_OPTIONAL_API_NAME(name)
Definition: optional_api.h:217
static struct ast_str * prompt
Definition: asterisk.c:2395
static int pw_cb(char *buf, int size, int rwflag, void *userdata)
setting of priv key
Definition: res_crypto.c:99
#define ASTERISK_GPL_KEY
The text the key() function should return.
Definition: module.h:38
Asterisk module definitions.
MD5 digest functions.
#define AST_RWLIST_TRAVERSE_SAFE_END
Definition: linkedlists.h:602
#define AST_KEY_PUBLIC
Definition: crypto.h:42
struct ast_key * ast_key_get(const char *key, int type)
Retrieve a key.
Definition: res_crypto.c:136
#define ASTERISK_FILE_VERSION(file, version)
Register/unregister a source code file with the core.
Definition: asterisk.h:180
static int crypto_init(void)
initialise the res_crypto module
Definition: res_crypto.c:635