Asterisk - The Open Source Telephony Project GIT-master-1f1c5bb
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 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 */
93EVP_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 */
107int 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 */
118X509 *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 */
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 */
144int 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 */
156int 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 */
165EVP_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 */
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 */
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 */
211int 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 */
243int 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 */
255int 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 */
264time_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 */
275char *crypto_get_cert_subject(X509 *cert, const char *short_name);
276
277/*!
278 * \brief Initialize the crypto utils
279 */
280int crypto_load(void);
281
282/*!
283 * \brief Clean up the crypto utils
284 */
285int crypto_unload(void);
286
287#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:185
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:402
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:41
int crypto_extract_raw_pubkey(EVP_PKEY *key, unsigned char **buffer)
Extract raw public key from EVP_PKEY.
Definition: crypto_utils.c:265
time_t crypto_asn_time_as_time_t(ASN1_TIME *at)
Return a time_t for an ASN1_TIME.
Definition: crypto_utils.c:431
EVP_PKEY * crypto_load_privkey_from_file(const char *filename)
Load a private key from a file.
Definition: crypto_utils.c:137
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:76
int crypto_extract_raw_privkey(EVP_PKEY *key, unsigned char **buffer)
Extract raw private key from EVP_PKEY.
Definition: crypto_utils.c:292
int crypto_get_raw_pubkey_from_cert(X509 *cert, unsigned char **raw_key)
Retrieve RAW public key from cert.
Definition: crypto_utils.c:279
int crypto_load(void)
Initialize the crypto utils.
Definition: crypto_utils.c:509
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:448
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:383
struct crypto_cert_store * crypto_create_cert_store(void)
Create an empty X509 store.
Definition: crypto_utils.c:315
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:238
int crypto_unload(void)
Clean up the crypto utils.
Definition: crypto_utils.c:514
X509 * crypto_load_cert_from_file(const char *filename)
Load an X509 Cert from a file.
Definition: crypto_utils.c:161
EVP_PKEY * crypto_load_private_key_from_memory(const char *buffer, size_t size)
Load a private key from memory.
Definition: crypto_utils.c:229
int crypto_show_cli_store(struct crypto_cert_store *store, int fd)
Dump a cert store to the asterisk CLI.
Definition: crypto_utils.c:360
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:103
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:333
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:170
X509_STORE * store
Definition: crypto_utils.h:171