Asterisk - The Open Source Telephony Project GIT-master-0bf3178
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 from a file
78 *
79 * \param filename PEM file
80 *
81 * \returns X509* or NULL on error
82 */
83X509 *crypto_load_cert_from_file(const char *filename);
84
85/*!
86 * \brief Load an X509 CRL from a PEM file
87 *
88 * \param filename PEM file
89 *
90 * \returns X509_CRL* or NULL on error
91 */
92X509_CRL *crypto_load_crl_from_file(const char *filename);
93
94/*!
95 * \brief Load a private key from memory
96 *
97 * \param buffer private key
98 * \param size buffer size
99 *
100 * \returns EVP_PKEY* or NULL on error
101 */
102EVP_PKEY *crypto_load_private_key_from_memory(const char *buffer, size_t size);
103
104/*!
105 * \brief Check if the supplied buffer has a private key
106 *
107 * \note This function can be used to check a certificate PEM file to
108 * see if it also has a private key in it.
109 *
110 * \param buffer arbitrary buffer
111 * \param size buffer size
112 *
113 * \retval 1 buffer has a private key
114 * \retval 0 buffer does not have a private key
115 */
116int crypto_has_private_key_from_memory(const char *buffer, size_t size);
117
118/*!
119 * \brief Load an X509 Cert from a NULL terminated buffer
120 *
121 * \param buffer containing the cert
122 * \param size size of the buffer.
123 * May be -1 if the buffer is NULL terminated.
124 *
125 * \returns X509* or NULL on error
126 */
127X509 *crypto_load_cert_from_memory(const char *buffer, size_t size);
128
129/*!
130 * \brief Retrieve RAW public key from cert
131 *
132 * \param cert The cert containing the extension
133 * \param raw_key Address of char * to place the raw key.
134 * Must be freed with ast_free after use
135 *
136 * \retval <=0 An error has occurred
137 * \retval >0 Length of raw key
138 */
140 unsigned char **raw_key);
141
142/*!
143 * \brief Extract raw public key from EVP_PKEY
144 *
145 * \param key Key to extract from
146 *
147 * \param buffer Pointer to unsigned char * to receive raw key
148 * Must be freed with ast_free after use
149 *
150 * \retval <=0 An error has occurred
151 * \retval >0 Length of raw key
152 */
153int crypto_extract_raw_pubkey(EVP_PKEY *key, unsigned char **buffer);
154
155/*!
156 * \brief Extract raw private key from EVP_PKEY
157 *
158 * \param key Key to extract from
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_privkey(EVP_PKEY *key, unsigned char **buffer);
166
167/*!
168 * \brief Load a private key from a file
169 *
170 * \param filename File to load from
171 *
172 * \returns EVP_PKEY *key or NULL on error
173 */
174EVP_PKEY *crypto_load_privkey_from_file(const char *filename);
175
176/*!
177 * \brief ao2 object wrapper for X509_STORE that provides locking and refcounting
178 */
180 X509_STORE *certs;
181 X509_STORE *crls;
182 /*!< The verification context needs a stack of CRLs, not the store */
183 STACK_OF(X509_CRL) *crl_stack;
184 X509_STORE *untrusted;
185 /*!< The verification context needs a stack of untrusted certs, not the store */
186 STACK_OF(X509) *untrusted_stack;
187};
188
189/*!
190 * \brief Free an X509 store
191 *
192 * \param store X509 Store to free
193 *
194 */
195#define crypto_free_cert_store(store) ao2_cleanup(store)
196
197/*!
198 * \brief Create an empty X509 store
199 *
200 * \returns crypto_cert_store * or NULL on error
201 */
203
204/*!
205 * \brief Dump a cert store to the asterisk CLI
206 *
207 * \param store X509 Store to dump
208 * \param fd The CLI fd to print to
209
210 * \retval Count of objects printed
211 */
212int crypto_show_cli_store(struct crypto_cert_store *store, int fd);
213
214/*!
215 * \brief Load an X509 Store with either certificates or CRLs
216 *
217 * \param store X509 Store to load
218 * \param file Certificate or CRL file to load or NULL
219 * \param path Path to directory with hashed certs or CRLs to load or NULL
220 *
221 * \note At least 1 file or path must be specified.
222 *
223 * \retval <= 0 failure
224 * \retval 0 success
225 */
226int crypto_load_cert_store(struct crypto_cert_store *store, const char *file,
227 const char *path);
228
229/*!
230 * \brief Load an X509 Store with certificate revocation lists
231 *
232 * \param store X509 Store to load
233 * \param file CRL file to load or NULL
234 * \param path Path to directory with hashed CRLs to load or NULL
235 *
236 * \note At least 1 file or path must be specified.
237 *
238 * \retval <= 0 failure
239 * \retval 0 success
240 */
241int crypto_load_crl_store(struct crypto_cert_store *store, const char *file,
242 const char *path);
243
244/*!
245 * \brief Load an X509 Store with untrusted certificates
246 *
247 * \param store X509 Store to load
248 * \param file Certificate file to load or NULL
249 * \param path Path to directory with hashed certs to load or NULL
250 *
251 * \note At least 1 file or path must be specified.
252 *
253 * \retval <= 0 failure
254 * \retval 0 success
255 */
256int crypto_load_untrusted_cert_store(struct crypto_cert_store *store, const char *file,
257 const char *path);
258
259/*!
260 * \brief Locks an X509 Store
261 *
262 * \param store X509 Store to lock
263 *
264 * \retval <= 0 failure
265 * \retval 0 success
266 */
267#define crypto_lock_cert_store(store) ao2_lock(store)
268
269/*!
270 * \brief Unlocks an X509 Store
271 *
272 * \param store X509 Store to unlock
273 *
274 * \retval <= 0 failure
275 * \retval 0 success
276 */
277#define crypto_unlock_cert_store(store) ao2_unlock(store)
278
279/*!
280 * \brief Check if the reftime is within the cert's valid dates
281 *
282 * \param cert The cert to check
283 * \param reftime to use or 0 to use current time
284 *
285 * \retval 1 Cert is valid
286 * \retval 0 Cert is not valid
287 */
288int crypto_is_cert_time_valid(X509 *cert, time_t reftime);
289
290/*!
291 * \brief Check if the cert is trusted
292 *
293 * \param store The CA store to check against
294 * \param cert The cert to check
295 * \param err_msg Optional pointer to a const char *
296 *
297 * \retval 1 Cert is trusted
298 * \retval 0 Cert is not trusted
299 */
300int crypto_is_cert_trusted(struct crypto_cert_store *store, X509 *cert, const char **err_msg);
301
302/*!
303 * \brief Return a time_t for an ASN1_TIME
304 *
305 * \param at ASN1_TIME
306 *
307 * \returns time_t corresponding to the ASN1_TIME
308 */
309time_t crypto_asn_time_as_time_t(ASN1_TIME *at);
310
311
312/*!
313 * \brief Returns the Subject (or component of Subject) from a certificate
314 *
315 * \param cert The X509 certificate
316 * \param short_name The upper case short name of the component to extract.
317 * May be NULL to extract the entire subject.
318 * \returns Entire subject or component. Must be freed with ast_free();
319 */
320char *crypto_get_cert_subject(X509 *cert, const char *short_name);
321
322/*!
323 * \brief Initialize the crypto utils
324 */
325int crypto_load(void);
326
327/*!
328 * \brief Clean up the crypto utils
329 */
330int crypto_unload(void);
331
332#endif /* CRYPTO_UTILS */
Asterisk main include file. File version handling, generic pbx functions.
X509 * crypto_load_cert_from_memory(const char *buffer, size_t size)
Load an X509 Cert from a NULL terminated buffer.
Definition: crypto_utils.c:213
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:622
int crypto_is_cert_trusted(struct crypto_cert_store *store, X509 *cert, const char **err_msg)
Check if the cert is trusted.
Definition: crypto_utils.c:740
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:293
time_t crypto_asn_time_as_time_t(ASN1_TIME *at)
Return a time_t for an ASN1_TIME.
Definition: crypto_utils.c:770
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:579
int crypto_extract_raw_privkey(EVP_PKEY *key, unsigned char **buffer)
Extract raw private key from EVP_PKEY.
Definition: crypto_utils.c:320
int crypto_get_raw_pubkey_from_cert(X509 *cert, unsigned char **raw_key)
Retrieve RAW public key from cert.
Definition: crypto_utils.c:307
int crypto_load(void)
Initialize the crypto utils.
Definition: crypto_utils.c:848
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:787
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:721
struct crypto_cert_store * crypto_create_cert_store(void)
Create an empty X509 store.
Definition: crypto_utils.c:390
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:266
int crypto_unload(void)
Clean up the crypto utils.
Definition: crypto_utils.c:853
X509 * crypto_load_cert_from_file(const char *filename)
Load an X509 Cert from a file.
Definition: crypto_utils.c:189
EVP_PKEY * crypto_load_private_key_from_memory(const char *buffer, size_t size)
Load a private key from memory.
Definition: crypto_utils.c:257
int crypto_show_cli_store(struct crypto_cert_store *store, int fd)
Dump a cert store to the asterisk CLI.
Definition: crypto_utils.c:665
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:563
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:179
STACK_OF(X509) *untrusted_stack
X509_STORE * untrusted
Definition: crypto_utils.h:184
X509_STORE * certs
Definition: crypto_utils.h:180
X509_STORE * crls
Definition: crypto_utils.h:181
STACK_OF(X509_CRL) *crl_stack