Asterisk - The Open Source Telephony Project  21.4.1
crypto_utils.h
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 2023, Sangoma Technologies Corporation
5  *
6  * George Joseph <gjoseph@sangoma.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 #ifndef _CRYPTO_UTILS_H
19 #define _CRYPTO_UTILS_H
20 
21 #include "openssl/x509.h"
22 #include "openssl/x509_vfy.h"
23 
24 #include "asterisk.h"
25 #include "asterisk/logger.h"
26 #include "asterisk/stringfields.h"
27 
28 /*!
29  * \brief Print a log message with any OpenSSL errors appended
30  *
31  * \param level Type of log event
32  * \param file Will be provided by the AST_LOG_* macro
33  * \param line Will be provided by the AST_LOG_* macro
34  * \param function Will be provided by the AST_LOG_* macro
35  * \param fmt This is what is important. The format is the same as your favorite breed of printf. You know how that works, right? :-)
36  */
37 void crypto_log_openssl(int level, char *file, int line,
38  const char *function, const char *fmt, ...)
39  __attribute__((format(printf, 5, 6)));
40 
41 /*!
42  * \brief Register a certificate extension to openssl
43  *
44  * \param oid The OID of the extension
45  * \param short_name The short name of the extension
46  * \param long_name The long name of the extension
47  *
48  * \retval <0 Extension was not successfully added
49  * \retval >= NID of the added extension
50  */
51 int crypto_register_x509_extension(const char *oid,
52  const char *short_name, const char *long_name);
53 
54 /*!
55  * \brief Return the data from a specific extension in a cert
56  *
57  * \param cert The cert containing the extension
58  * \param nid The NID of the extension
59  * (0 to search locally registered extensions by short_name)
60  * \param short_name The short name of the extension
61  * (only for locally registered extensions)
62  *
63  * \note Either nid or short_name may be supplied. If both are,
64  * nid takes precedence.
65  * \note The extension nid may be any of the built-in values
66  * in openssl/obj_mac.h or a NID returned by
67  * ast_crypto_register_x509_extension().
68  *
69  * \returns The data for the extension or NULL if not found
70  *
71  * \warning Do NOT attempt to free the returned buffer.
72  */
73 ASN1_OCTET_STRING *crypto_get_cert_extension_data(X509 *cert, int nid,
74  const char *short_name);
75 
76 /*!
77  * \brief Load an X509 Cert from a file
78  *
79  * \param filename PEM file
80  *
81  * \returns X509* or NULL on error
82  */
83 X509 *crypto_load_cert_from_file(const char *filename);
84 
85 /*!
86  * \brief Load a private key from memory
87  *
88  * \param buffer private key
89  * \param size buffer size
90  *
91  * \returns EVP_PKEY* or NULL on error
92  */
93 EVP_PKEY *crypto_load_private_key_from_memory(const char *buffer, size_t size);
94 
95 /*!
96  * \brief Check if the supplied buffer has a private key
97  *
98  * \note This function can be used to check a certificate PEM file to
99  * see if it also has a private key in it.
100  *
101  * \param buffer arbitrary buffer
102  * \param size buffer size
103  *
104  * \retval 1 buffer has a private key
105  * \retval 0 buffer does not have a private key
106  */
107 int crypto_has_private_key_from_memory(const char *buffer, size_t size);
108 
109 /*!
110  * \brief Load an X509 Cert from a NULL terminated buffer
111  *
112  * \param buffer containing the cert
113  * \param size size of the buffer.
114  * May be -1 if the buffer is NULL terminated.
115  *
116  * \returns X509* or NULL on error
117  */
118 X509 *crypto_load_cert_from_memory(const char *buffer, size_t size);
119 
120 /*!
121  * \brief Retrieve RAW public key from cert
122  *
123  * \param cert The cert containing the extension
124  * \param raw_key Address of char * to place the raw key.
125  * Must be freed with ast_free after use
126  *
127  * \retval <=0 An error has occurred
128  * \retval >0 Length of raw key
129  */
130 int crypto_get_raw_pubkey_from_cert(X509 *cert,
131  unsigned char **raw_key);
132 
133 /*!
134  * \brief Extract raw public key from EVP_PKEY
135  *
136  * \param key Key to extract from
137  *
138  * \param buffer Pointer to unsigned char * to receive raw key
139  * Must be freed with ast_free after use
140  *
141  * \retval <=0 An error has occurred
142  * \retval >0 Length of raw key
143  */
144 int crypto_extract_raw_pubkey(EVP_PKEY *key, unsigned char **buffer);
145 
146 /*!
147  * \brief Extract raw private key from EVP_PKEY
148  *
149  * \param key Key to extract from
150  * \param buffer Pointer to unsigned char * to receive raw key
151  * Must be freed with ast_free after use
152  *
153  * \retval <=0 An error has occurred
154  * \retval >0 Length of raw key
155  */
156 int crypto_extract_raw_privkey(EVP_PKEY *key, unsigned char **buffer);
157 
158 /*!
159  * \brief Load a private key from a file
160  *
161  * \param filename File to load from
162  *
163  * \returns EVP_PKEY *key or NULL on error
164  */
165 EVP_PKEY *crypto_load_privkey_from_file(const char *filename);
166 
167 /*!
168  * \brief ao2 object wrapper for X509_STORE that provides locking and refcounting
169  */
171  X509_STORE *store;
172 };
173 
174 /*!
175  * \brief Free an X509 store
176  *
177  * \param store X509 Store to free
178  *
179  */
180 #define crypto_free_cert_store(store) ao2_cleanup(store)
181 
182 /*!
183  * \brief Create an empty X509 store
184  *
185  * \returns crypto_cert_store * or NULL on error
186  */
187 struct crypto_cert_store *crypto_create_cert_store(void);
188 
189 /*!
190  * \brief Dump a cert store to the asterisk CLI
191  *
192  * \param store X509 Store to dump
193  * \param fd The CLI fd to print to
194 
195  * \retval Count of objects printed
196  */
197 int crypto_show_cli_store(struct crypto_cert_store *store, int fd);
198 
199 /*!
200  * \brief Load an X509 Store with either certificates or CRLs
201  *
202  * \param store X509 Store to load
203  * \param file Certificate or CRL file to load or NULL
204  * \param path Path to directory with hashed certs or CRLs to load or NULL
205  *
206  * \note At least 1 file or path must be specified.
207  *
208  * \retval <= 0 failure
209  * \retval 0 success
210  */
211 int crypto_load_cert_store(struct crypto_cert_store *store, const char *file,
212  const char *path);
213 
214 /*!
215  * \brief Locks an X509 Store
216  *
217  * \param store X509 Store to lock
218  *
219  * \retval <= 0 failure
220  * \retval 0 success
221  */
222 #define crypto_lock_cert_store(store) ao2_lock(store)
223 
224 /*!
225  * \brief Unlocks an X509 Store
226  *
227  * \param store X509 Store to unlock
228  *
229  * \retval <= 0 failure
230  * \retval 0 success
231  */
232 #define crypto_unlock_cert_store(store) ao2_unlock(store)
233 
234 /*!
235  * \brief Check if the reftime is within the cert's valid dates
236  *
237  * \param cert The cert to check
238  * \param reftime to use or 0 to use current time
239  *
240  * \retval 1 Cert is valid
241  * \retval 0 Cert is not valid
242  */
243 int crypto_is_cert_time_valid(X509 *cert, time_t reftime);
244 
245 /*!
246  * \brief Check if the cert is trusted
247  *
248  * \param store The CA store to check against
249  * \param cert The cert to check
250  * \param err_msg Optional pointer to a const char *
251  *
252  * \retval 1 Cert is trusted
253  * \retval 0 Cert is not trusted
254  */
255 int crypto_is_cert_trusted(struct crypto_cert_store *store, X509 *cert, const char **err_msg);
256 
257 /*!
258  * \brief Return a time_t for an ASN1_TIME
259  *
260  * \param at ASN1_TIME
261  *
262  * \returns time_t corresponding to the ASN1_TIME
263  */
264 time_t crypto_asn_time_as_time_t(ASN1_TIME *at);
265 
266 
267 /*!
268  * \brief Returns the Subject (or component of Subject) from a certificate
269  *
270  * \param cert The X509 certificate
271  * \param short_name The upper case short name of the component to extract.
272  * May be NULL to extract the entire subject.
273  * \returns Entire subject or component. Must be freed with ast_free();
274  */
275 char *crypto_get_cert_subject(X509 *cert, const char *short_name);
276 
277 /*!
278  * \brief Initialize the crypto utils
279  */
280 int crypto_load(void);
281 
282 /*!
283  * \brief Clean up the crypto utils
284  */
285 int crypto_unload(void);
286 
287 #endif /* CRYPTO_UTILS */
Asterisk main include file. File version handling, generic pbx functions.
ao2 object wrapper for X509_STORE that provides locking and refcounting
Definition: crypto_utils.h:170
Support for logging to various files, console and syslog Configuration in file logger.conf.
static void crypto_load(int ifd, int ofd)
refresh RSA keys from file
Definition: res_crypto.c:819