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