loader: Sync load- and build-time deps.
[asterisk/asterisk.git] / res / res_stir_shaken / stir_shaken.c
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 2020, Sangoma Technologies Corporation
5  *
6  * Kevin Harwell <kharwell@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 Internal stir/shaken utilities
22  */
23
24 #include "asterisk.h"
25
26 #include "asterisk/cli.h"
27 #include "asterisk/sorcery.h"
28
29 #include "stir_shaken.h"
30 #include "asterisk/res_stir_shaken.h"
31
32 int stir_shaken_cli_show(void *obj, void *arg, int flags)
33 {
34         struct ast_cli_args *a = arg;
35         struct ast_variable *options;
36         struct ast_variable *i;
37
38         if (!obj) {
39                 ast_cli(a->fd, "No stir/shaken configuration found\n");
40                 return 0;
41         }
42
43         options = ast_variable_list_sort(ast_sorcery_objectset_create2(
44                 ast_stir_shaken_sorcery(), obj, AST_HANDLER_ONLY_STRING));
45         if (!options) {
46                 return 0;
47         }
48
49         ast_cli(a->fd, "%s: %s\n", ast_sorcery_object_get_type(obj),
50                 ast_sorcery_object_get_id(obj));
51
52         for (i = options; i; i = i->next) {
53                 ast_cli(a->fd, "\t%s: %s\n", i->name, i->value);
54         }
55
56         ast_cli(a->fd, "\n");
57
58         ast_variables_destroy(options);
59
60         return 0;
61 }
62
63 char *stir_shaken_tab_complete_name(const char *word, struct ao2_container *container)
64 {
65         void *obj;
66         struct ao2_iterator it;
67         int wordlen = strlen(word);
68         int ret;
69
70         it = ao2_iterator_init(container, 0);
71         while ((obj = ao2_iterator_next(&it))) {
72                 if (!strncasecmp(word, ast_sorcery_object_get_id(obj), wordlen)) {
73                         ret = ast_cli_completion_add(ast_strdup(ast_sorcery_object_get_id(obj)));
74                         if (ret) {
75                                 ao2_ref(obj, -1);
76                                 break;
77                         }
78                 }
79                 ao2_ref(obj, -1);
80         }
81         ao2_iterator_destroy(&it);
82
83         return NULL;
84 }
85
86 EVP_PKEY *stir_shaken_read_key(const char *path, int priv)
87 {
88         EVP_PKEY *key = NULL;
89         FILE *fp;
90
91         fp = fopen(path, "r");
92         if (!fp) {
93                 ast_log(LOG_ERROR, "Failed to read %s key file '%s'\n", priv ? "private" : "public", path);
94                 return NULL;
95         }
96
97         if (priv) {
98                 key = PEM_read_PrivateKey(fp, NULL, NULL, NULL);
99         } else {
100                 key = PEM_read_PUBKEY(fp, NULL, NULL, NULL);
101         }
102
103         if (!key) {
104                 ast_log(LOG_ERROR, "Failed to read %s key from file '%s'\n", priv ? "private" : "public", path);
105                 fclose(fp);
106                 return NULL;
107         }
108
109         if (EVP_PKEY_id(key) != EVP_PKEY_EC) {
110                 ast_log(LOG_ERROR, "%s key from '%s' must be of type EVP_PKEY_EC\n", priv ? "private" : "public", path);
111                 fclose(fp);
112                 EVP_PKEY_free(key);
113                 return NULL;
114         }
115
116         fclose(fp);
117
118         return key;
119 }