Asterisk - The Open Source Telephony Project GIT-master-4522eb1
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Macros Modules Pages
crypto_utils.h
Go to the documentation of this file.
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"
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 */
37void 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 */
51int 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 */
73ASN1_OCTET_STRING *crypto_get_cert_extension_data(X509 *cert, int nid,
74 const char *short_name);
75
76/*!
77 * \brief Load an X509 Cert and any chained certs from a file
78 *
79 * \param filename PEM file
80 * \param chain_stack The address of a STACK_OF(X509) pointer to receive the
81 * chain of certificates if any.
82 *
83 * \note The caller is responsible for freeing the cert_chain stack and
84 * any certs in it.
85 *
86 * \returns X509* or NULL on error
87 */
88X509 *crypto_load_cert_chain_from_file(const char *filename,
89 STACK_OF(X509) **chain_stack);
90
91/*!
92 * \brief Load an X509 CRL from a PEM file
93 *
94 * \param filename PEM file
95 *
96 * \returns X509_CRL* or NULL on error
97 */
98X509_CRL *crypto_load_crl_from_file(const char *filename);
99
100/*!
101 * \brief Load a private key from memory
102 *
103 * \param buffer private key
104 * \param size buffer size
105 *
106 * \returns EVP_PKEY* or NULL on error
107 */
108EVP_PKEY *crypto_load_private_key_from_memory(const char *buffer, size_t size);
109
110/*!
111 * \brief Check if the supplied buffer has a private key
112 *
113 * \note This function can be used to check a certificate PEM file to
114 * see if it also has a private key in it.
115 *
116 * \param buffer arbitrary buffer
117 * \param size buffer size
118 *
119 * \retval 1 buffer has a private key
120 * \retval 0 buffer does not have a private key
121 */
122int crypto_has_private_key_from_memory(const char *buffer, size_t size);
123
124/*!
125 * \brief Load an X509 Cert and any chained certs from a NULL terminated buffer
126 *
127 * \param buffer containing the cert
128 * \param size size of the buffer.
129 * May be -1 if the buffer is NULL terminated.
130 * \param chain_stack The address of a STACK_OF(X509) pointer to receive the
131 * chain of certificates if any.
132 *
133 * \note The caller is responsible for freeing the cert_chain stack and
134 * any certs in it.
135 *
136 * \returns X509* or NULL on error
137 */
138X509 *crypto_load_cert_chain_from_memory(const char *buffer, size_t size,
139 STACK_OF(X509) **cert_chain);
140
141/*!
142 * \brief Retrieve RAW public key from cert
143 *
144 * \param cert The cert containing the extension
145 * \param raw_key Address of char * to place the raw key.
146 * Must be freed with ast_free after use
147 *
148 * \retval <=0 An error has occurred
149 * \retval >0 Length of raw key
150 */
152 unsigned char **raw_key);
153
154/*!
155 * \brief Extract raw public key from EVP_PKEY
156 *
157 * \param key Key to extract from
158 *
159 * \param buffer Pointer to unsigned char * to receive raw key
160 * Must be freed with ast_free after use
161 *
162 * \retval <=0 An error has occurred
163 * \retval >0 Length of raw key
164 */
165int crypto_extract_raw_pubkey(EVP_PKEY *key, unsigned char **buffer);
166
167/*!
168 * \brief Extract raw private key from EVP_PKEY
169 *
170 * \param key Key to extract from
171 * \param buffer Pointer to unsigned char * to receive raw key
172 * Must be freed with ast_free after use
173 *
174 * \retval <=0 An error has occurred
175 * \retval >0 Length of raw key
176 */
177int crypto_extract_raw_privkey(EVP_PKEY *key, unsigned char **buffer);
178
179/*!
180 * \brief Load a private key from a file
181 *
182 * \param filename File to load from
183 *
184 * \returns EVP_PKEY *key or NULL on error
185 */
186EVP_PKEY *crypto_load_privkey_from_file(const char *filename);
187
188/*!
189 * \brief ao2 object wrapper for X509_STORE that provides locking and refcounting
190 */
192 X509_STORE *certs;
193 X509_STORE *crls;
194 /*!< The verification context needs a stack of CRLs, not the store */
195 STACK_OF(X509_CRL) *crl_stack;
196 X509_STORE *untrusted;
197 /*!< The verification context needs a stack of untrusted certs, not the store */
198 STACK_OF(X509) *untrusted_stack;
199};
200
201/*!
202 * \brief Free an X509 store
203 *
204 * \param store X509 Store to free
205 *
206 */
207#define crypto_free_cert_store(store) ao2_cleanup(store)
208
209/*!
210 * \brief Create an empty X509 store
211 *
212 * \returns crypto_cert_store * or NULL on error
213 */
215
216/*!
217 * \brief Dump a cert store to the asterisk CLI
218 *
219 * \param store X509 Store to dump
220 * \param fd The CLI fd to print to
221
222 * \retval Count of objects printed
223 */
224int crypto_show_cli_store(struct crypto_cert_store *store, int fd);
225
226/*!
227 * \brief Load an X509 Store with either certificates or CRLs
228 *
229 * \param store X509 Store to load
230 * \param file Certificate or CRL file to load or NULL
231 * \param path Path to directory with hashed certs or CRLs to load or NULL
232 *
233 * \note At least 1 file or path must be specified.
234 *
235 * \retval <= 0 failure
236 * \retval 0 success
237 */
238int crypto_load_cert_store(struct crypto_cert_store *store, const char *file,
239 const char *path);
240
241/*!
242 * \brief Load an X509 Store with certificate revocation lists
243 *
244 * \param store X509 Store to load
245 * \param file CRL file to load or NULL
246 * \param path Path to directory with hashed CRLs to load or NULL
247 *
248 * \note At least 1 file or path must be specified.
249 *
250 * \retval <= 0 failure
251 * \retval 0 success
252 */
253int crypto_load_crl_store(struct crypto_cert_store *store, const char *file,
254 const char *path);
255
256/*!
257 * \brief Load an X509 Store with untrusted certificates
258 *
259 * \param store X509 Store to load
260 * \param file Certificate file to load or NULL
261 * \param path Path to directory with hashed certs to load or NULL
262 *
263 * \note At least 1 file or path must be specified.
264 *
265 * \retval <= 0 failure
266 * \retval 0 success
267 */
268int crypto_load_untrusted_cert_store(struct crypto_cert_store *store, const char *file,
269 const char *path);
270
271/*!
272 * \brief Locks an X509 Store
273 *
274 * \param store X509 Store to lock
275 *
276 * \retval <= 0 failure
277 * \retval 0 success
278 */
279#define crypto_lock_cert_store(store) ao2_lock(store)
280
281/*!
282 * \brief Unlocks an X509 Store
283 *
284 * \param store X509 Store to unlock
285 *
286 * \retval <= 0 failure
287 * \retval 0 success
288 */
289#define crypto_unlock_cert_store(store) ao2_unlock(store)
290
291/*!
292 * \brief Check if the reftime is within the cert's valid dates
293 *
294 * \param cert The cert to check
295 * \param reftime to use or 0 to use current time
296 *
297 * \retval 1 Cert is valid
298 * \retval 0 Cert is not valid
299 */
300int crypto_is_cert_time_valid(X509 *cert, time_t reftime);
301
302/*!
303 * \brief Check if the cert is trusted
304 *
305 * \param store The CA store to check against
306 * \param cert The cert to check
307 * \param cert_chain An untrusted certificate chain that may have accompanied the cert.
308 * \param err_msg Optional pointer to a const char *
309 *
310 * \retval 1 Cert is trusted
311 * \retval 0 Cert is not trusted
312 */
313int crypto_is_cert_trusted(struct crypto_cert_store *store, X509 *cert,
314 STACK_OF(X509) *cert_chain, const char **err_msg);
315
316/*!
317 * \brief Return a time_t for an ASN1_TIME
318 *
319 * \param at ASN1_TIME
320 *
321 * \returns time_t corresponding to the ASN1_TIME
322 */
323time_t crypto_asn_time_as_time_t(ASN1_TIME *at);
324
325
326/*!
327 * \brief Returns the Subject (or component of Subject) from a certificate
328 *
329 * \param cert The X509 certificate
330 * \param short_name The upper case short name of the component to extract.
331 * May be NULL to extract the entire subject.
332 * \returns Entire subject or component. Must be freed with ast_free();
333 */
334char *crypto_get_cert_subject(X509 *cert, const char *short_name);
335
336/*!
337 * \brief Initialize the crypto utils
338 */
339int crypto_load(void);
340
341/*!
342 * \brief Clean up the crypto utils
343 */
344int crypto_unload(void);
345
346#endif /* CRYPTO_UTILS */
Asterisk main include file. File version handling, generic pbx functions.
int crypto_load_crl_store(struct crypto_cert_store *store, const char *file, const char *path)
Load an X509 Store with certificate revocation lists.
Definition: crypto_utils.c:711
X509 * crypto_load_cert_chain_from_memory(const char *buffer, size_t size, STACK_OF(X509) **cert_chain)
Load an X509 Cert and any chained certs from a NULL terminated buffer.
Definition: crypto_utils.c:266
void crypto_log_openssl(int level, char *file, int line, const char *function, const char *fmt,...)
Print a log message with any OpenSSL errors appended.
Definition: crypto_utils.c:45
int crypto_extract_raw_pubkey(EVP_PKEY *key, unsigned char **buffer)
Extract raw public key from EVP_PKEY.
Definition: crypto_utils.c:382
time_t crypto_asn_time_as_time_t(ASN1_TIME *at)
Return a time_t for an ASN1_TIME.
Definition: crypto_utils.c:900
X509_CRL * crypto_load_crl_from_file(const char *filename)
Load an X509 CRL from a PEM file.
Definition: crypto_utils.c:165
EVP_PKEY * crypto_load_privkey_from_file(const char *filename)
Load a private key from a file.
Definition: crypto_utils.c:141
int crypto_register_x509_extension(const char *oid, const char *short_name, const char *long_name)
Register a certificate extension to openssl.
Definition: crypto_utils.c:80
int crypto_load_untrusted_cert_store(struct crypto_cert_store *store, const char *file, const char *path)
Load an X509 Store with untrusted certificates.
Definition: crypto_utils.c:668
int crypto_extract_raw_privkey(EVP_PKEY *key, unsigned char **buffer)
Extract raw private key from EVP_PKEY.
Definition: crypto_utils.c:409
int crypto_get_raw_pubkey_from_cert(X509 *cert, unsigned char **raw_key)
Retrieve RAW public key from cert.
Definition: crypto_utils.c:396
int crypto_load(void)
Initialize the crypto utils.
Definition: crypto_utils.c:978
char * crypto_get_cert_subject(X509 *cert, const char *short_name)
Returns the Subject (or component of Subject) from a certificate.
Definition: crypto_utils.c:917
int crypto_is_cert_time_valid(X509 *cert, time_t reftime)
Check if the reftime is within the cert's valid dates.
Definition: crypto_utils.c:810
struct crypto_cert_store * crypto_create_cert_store(void)
Create an empty X509 store.
Definition: crypto_utils.c:479
int crypto_has_private_key_from_memory(const char *buffer, size_t size)
Check if the supplied buffer has a private key.
Definition: crypto_utils.c:355
int crypto_unload(void)
Clean up the crypto utils.
Definition: crypto_utils.c:983
int crypto_is_cert_trusted(struct crypto_cert_store *store, X509 *cert, STACK_OF(X509) *cert_chain, const char **err_msg)
Check if the cert is trusted.
Definition: crypto_utils.c:829
X509 * crypto_load_cert_chain_from_file(const char *filename, STACK_OF(X509) **chain_stack)
Load an X509 Cert and any chained certs from a file.
Definition: crypto_utils.c:203
EVP_PKEY * crypto_load_private_key_from_memory(const char *buffer, size_t size)
Load a private key from memory.
Definition: crypto_utils.c:346
int crypto_show_cli_store(struct crypto_cert_store *store, int fd)
Dump a cert store to the asterisk CLI.
Definition: crypto_utils.c:754
ASN1_OCTET_STRING * crypto_get_cert_extension_data(X509 *cert, int nid, const char *short_name)
Return the data from a specific extension in a cert.
Definition: crypto_utils.c:107
int crypto_load_cert_store(struct crypto_cert_store *store, const char *file, const char *path)
Load an X509 Store with either certificates or CRLs.
Definition: crypto_utils.c:652
Support for logging to various files, console and syslog Configuration in file logger....
ao2 object wrapper for X509_STORE that provides locking and refcounting
Definition: crypto_utils.h:191
STACK_OF(X509) *untrusted_stack
X509_STORE * untrusted
Definition: crypto_utils.h:196
X509_STORE * certs
Definition: crypto_utils.h:192
X509_STORE * crls
Definition: crypto_utils.h:193
STACK_OF(X509_CRL) *crl_stack