Asterisk - The Open Source Telephony Project GIT-master-f36a736
Data Structures | Macros | Functions
crypto_utils.h File Reference
#include "openssl/x509.h"
#include "openssl/x509_vfy.h"
#include "asterisk.h"
#include "asterisk/logger.h"
#include "asterisk/stringfields.h"
Include dependency graph for crypto_utils.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  crypto_cert_store
 ao2 object wrapper for X509_STORE that provides locking and refcounting More...
 

Macros

#define crypto_free_cert_store(store)   ao2_cleanup(store)
 Free an X509 store. More...
 
#define crypto_lock_cert_store(store)   ao2_lock(store)
 Locks an X509 Store. More...
 
#define crypto_unlock_cert_store(store)   ao2_unlock(store)
 Unlocks an X509 Store. More...
 

Functions

time_t crypto_asn_time_as_time_t (ASN1_TIME *at)
 Return a time_t for an ASN1_TIME. More...
 
struct crypto_cert_storecrypto_create_cert_store (void)
 Create an empty X509 store. More...
 
int crypto_extract_raw_privkey (EVP_PKEY *key, unsigned char **buffer)
 Extract raw private key from EVP_PKEY. More...
 
int crypto_extract_raw_pubkey (EVP_PKEY *key, unsigned char **buffer)
 Extract raw public key from EVP_PKEY. More...
 
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. More...
 
char * crypto_get_cert_subject (X509 *cert, const char *short_name)
 Returns the Subject (or component of Subject) from a certificate. More...
 
int crypto_get_raw_pubkey_from_cert (X509 *cert, unsigned char **raw_key)
 Retrieve RAW public key from cert. More...
 
int crypto_has_private_key_from_memory (const char *buffer, size_t size)
 Check if the supplied buffer has a private key. More...
 
int crypto_is_cert_time_valid (X509 *cert, time_t reftime)
 Check if the reftime is within the cert's valid dates. More...
 
int crypto_is_cert_trusted (struct crypto_cert_store *store, X509 *cert, const char **err_msg)
 Check if the cert is trusted. More...
 
int crypto_load (void)
 Initialize the crypto utils. More...
 
X509 * crypto_load_cert_from_file (const char *filename)
 Load an X509 Cert from a file. More...
 
X509 * crypto_load_cert_from_memory (const char *buffer, size_t size)
 Load an X509 Cert from a NULL terminated buffer. More...
 
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. More...
 
X509_CRL * crypto_load_crl_from_file (const char *filename)
 Load an X509 CRL from a PEM file. More...
 
int crypto_load_crl_store (struct crypto_cert_store *store, const char *file, const char *path)
 Load an X509 Store with certificate revocation lists. More...
 
EVP_PKEY * crypto_load_private_key_from_memory (const char *buffer, size_t size)
 Load a private key from memory. More...
 
EVP_PKEY * crypto_load_privkey_from_file (const char *filename)
 Load a private key from a file. More...
 
int crypto_load_untrusted_cert_store (struct crypto_cert_store *store, const char *file, const char *path)
 Load an X509 Store with untrusted certificates. More...
 
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. More...
 
int crypto_register_x509_extension (const char *oid, const char *short_name, const char *long_name)
 Register a certificate extension to openssl. More...
 
int crypto_show_cli_store (struct crypto_cert_store *store, int fd)
 Dump a cert store to the asterisk CLI. More...
 
int crypto_unload (void)
 Clean up the crypto utils. More...
 

Macro Definition Documentation

◆ crypto_free_cert_store

#define crypto_free_cert_store (   store)    ao2_cleanup(store)

Free an X509 store.

Parameters
storeX509 Store to free

Definition at line 195 of file crypto_utils.h.

◆ crypto_lock_cert_store

#define crypto_lock_cert_store (   store)    ao2_lock(store)

Locks an X509 Store.

Parameters
storeX509 Store to lock
Return values
<=0 failure
0success

Definition at line 267 of file crypto_utils.h.

◆ crypto_unlock_cert_store

#define crypto_unlock_cert_store (   store)    ao2_unlock(store)

Unlocks an X509 Store.

Parameters
storeX509 Store to unlock
Return values
<=0 failure
0success

Definition at line 277 of file crypto_utils.h.

Function Documentation

◆ crypto_asn_time_as_time_t()

time_t crypto_asn_time_as_time_t ( ASN1_TIME *  at)

Return a time_t for an ASN1_TIME.

Parameters
atASN1_TIME
Returns
time_t corresponding to the ASN1_TIME

Definition at line 770 of file crypto_utils.c.

771{
772 int pday;
773 int psec;
774 time_t rt = time(NULL);
775
776 if (!ASN1_TIME_diff(&pday, &psec, NULL, at)) {
777 crypto_log_openssl(LOG_ERROR, "Unable to calculate time diff\n");
778 return 0;
779 }
780
781 rt += ((pday * SECS_PER_DAY) + psec);
782
783 return rt;
784}
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
#define SECS_PER_DAY
Definition: crypto_utils.c:769
#define LOG_ERROR
#define NULL
Definition: resample.c:96

References crypto_log_openssl(), LOG_ERROR, NULL, and SECS_PER_DAY.

Referenced by add_cert_expiration_to_astdb().

◆ crypto_create_cert_store()

struct crypto_cert_store * crypto_create_cert_store ( void  )

Create an empty X509 store.

Returns
crypto_cert_store * or NULL on error

Definition at line 390 of file crypto_utils.c.

391{
392 struct crypto_cert_store *store = ao2_alloc(sizeof(*store), crypto_cert_store_destructor);
393 if (!store) {
394 ast_log(LOG_ERROR, "Failed to create crypto_cert_store\n");
395 return NULL;
396 }
397
398 store->certs = X509_STORE_new();
399 if (!store->certs) {
400 crypto_log_openssl(LOG_ERROR, "Failed to create X509_STORE\n");
401 ao2_ref(store, -1);
402 return NULL;
403 }
404
405 store->untrusted = X509_STORE_new();
406 if (!store->untrusted) {
407 crypto_log_openssl(LOG_ERROR, "Failed to create untrusted X509_STORE\n");
408 ao2_ref(store, -1);
409 return NULL;
410 }
411 store->untrusted_stack = sk_X509_new_null();
412 if (!store->untrusted_stack) {
413 crypto_log_openssl(LOG_ERROR, "Failed to create untrusted stack\n");
414 ao2_ref(store, -1);
415 return NULL;
416 }
417
418 store->crls = X509_STORE_new();
419 if (!store->crls) {
420 crypto_log_openssl(LOG_ERROR, "Failed to create CRL X509_STORE\n");
421 ao2_ref(store, -1);
422 return NULL;
423 }
424 store->crl_stack = sk_X509_CRL_new_null();
425 if (!store->crl_stack) {
426 crypto_log_openssl(LOG_ERROR, "Failed to create CRL stack\n");
427 ao2_ref(store, -1);
428 return NULL;
429 }
430
431 return store;
432}
#define ast_log
Definition: astobj2.c:42
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:409
static void crypto_cert_store_destructor(void *obj)
Definition: crypto_utils.c:369
ao2 object wrapper for X509_STORE that provides locking and refcounting
Definition: crypto_utils.h:179
X509_STORE * untrusted
Definition: crypto_utils.h:184
X509_STORE * certs
Definition: crypto_utils.h:180
X509_STORE * crls
Definition: crypto_utils.h:181

References ao2_alloc, ao2_ref, ast_log, crypto_cert_store::certs, crypto_cert_store::crls, crypto_cert_store_destructor(), crypto_log_openssl(), LOG_ERROR, NULL, and crypto_cert_store::untrusted.

Referenced by vs_check_common_config().

◆ crypto_extract_raw_privkey()

int crypto_extract_raw_privkey ( EVP_PKEY *  key,
unsigned char **  buffer 
)

Extract raw private key from EVP_PKEY.

Parameters
keyKey to extract from
bufferPointer to unsigned char * to receive raw key Must be freed with ast_free after use
Return values
<=0An error has occurred
>0Length of raw key

Definition at line 320 of file crypto_utils.c.

321{
322 RAII_VAR(BIO *, bio, NULL, BIO_free_all);
323
324 bio = BIO_new(BIO_s_mem());
325
326 if (!bio || (PEM_write_bio_PrivateKey(bio, key, NULL, NULL, 0, NULL, NULL) <= 0)) {
327 crypto_log_openssl(LOG_ERROR, "Unable to write privkey to BIO\n");
328 return -1;
329 }
330
331 return dump_mem_bio(bio, buffer);
332}
static int dump_mem_bio(BIO *bio, unsigned char **buffer)
Definition: crypto_utils.c:273
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:941

References crypto_log_openssl(), dump_mem_bio(), LOG_ERROR, NULL, and RAII_VAR.

Referenced by as_check_common_config().

◆ crypto_extract_raw_pubkey()

int crypto_extract_raw_pubkey ( EVP_PKEY *  key,
unsigned char **  buffer 
)

Extract raw public key from EVP_PKEY.

Parameters
keyKey to extract from
bufferPointer to unsigned char * to receive raw key Must be freed with ast_free after use
Return values
<=0An error has occurred
>0Length of raw key

Definition at line 293 of file crypto_utils.c.

294{
295 RAII_VAR(BIO *, bio, NULL, BIO_free_all);
296
297 bio = BIO_new(BIO_s_mem());
298
299 if (!bio || (PEM_write_bio_PUBKEY(bio, key) <= 0)) {
300 crypto_log_openssl(LOG_ERROR, "Unable to write pubkey to BIO\n");
301 return -1;
302 }
303
304 return dump_mem_bio(bio, buffer);
305}

References crypto_log_openssl(), dump_mem_bio(), LOG_ERROR, NULL, and RAII_VAR.

Referenced by crypto_get_raw_pubkey_from_cert().

◆ crypto_get_cert_extension_data()

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.

Parameters
certThe cert containing the extension
nidThe NID of the extension (0 to search locally registered extensions by short_name)
short_nameThe short name of the extension (only for locally registered extensions)
Note
Either nid or short_name may be supplied. If both are, nid takes precedence.
The extension nid may be any of the built-in values in openssl/obj_mac.h or a NID returned by ast_crypto_register_x509_extension().
Returns
The data for the extension or NULL if not found
Warning
Do NOT attempt to free the returned buffer.

Definition at line 107 of file crypto_utils.c.

109{
110 int ex_idx;
111 X509_EXTENSION *ex;
112
113 if (nid <= 0) {
114 nid = OBJ_sn2nid(short_name);
115 if (nid == NID_undef) {
116 ast_log(LOG_ERROR, "Extension object for %s not found\n", short_name);
117 return NULL;
118 }
119 } else {
120 const char *tmp = OBJ_nid2sn(nid);
121 if (!tmp) {
122 ast_log(LOG_ERROR, "Extension object for NID %d not found\n", nid);
123 return NULL;
124 }
125 }
126
127 ex_idx = X509_get_ext_by_NID(cert, nid, -1);
128 if (ex_idx < 0) {
129 ast_log(LOG_ERROR, "Extension index not found in certificate\n");
130 return NULL;
131 }
132 ex = X509_get_ext(cert, ex_idx);
133 if (!ex) {
134 ast_log(LOG_ERROR, "Extension not found in certificate\n");
135 return NULL;
136 }
137
138 return X509_EXTENSION_get_data(ex);
139}
static int tmp()
Definition: bt_open.c:389

References ast_log, LOG_ERROR, NULL, and tmp().

Referenced by check_tn_auth_list().

◆ crypto_get_cert_subject()

char * crypto_get_cert_subject ( X509 *  cert,
const char *  short_name 
)

Returns the Subject (or component of Subject) from a certificate.

Parameters
certThe X509 certificate
short_nameThe upper case short name of the component to extract. May be NULL to extract the entire subject.
Returns
Entire subject or component. Must be freed with ast_free();

Definition at line 787 of file crypto_utils.c.

788{
789 size_t len = 0;
790 RAII_VAR(char *, buffer, NULL, ast_std_free);
791 char *search_buff = NULL;
792 char *search = NULL;
793 size_t search_len = 0;
794 char *rtn = NULL;
795 char *line = NULL;
796 /*
797 * If short_name was supplied, we want a multiline subject
798 * with each component on a separate line. This makes it easier
799 * to iterate over the components to find the one we want.
800 * Otherwise, we just want the whole subject on one line.
801 */
802 unsigned long flags =
803 short_name ? XN_FLAG_FN_SN | XN_FLAG_SEP_MULTILINE : XN_FLAG_ONELINE;
804 FILE *fp = open_memstream(&buffer, &len);
805 BIO *bio = fp ? BIO_new_fp(fp, BIO_CLOSE) : NULL;
806 X509_NAME *subject = X509_get_subject_name(cert);
807 int rc = 0;
808
809 if (!fp || !bio || !subject) {
810 return NULL;
811 }
812
813 rc = X509_NAME_print_ex(bio, subject, 0, flags);
814 BIO_free(bio);
815 if (rc < 0) {
816 return NULL;
817 }
818
819 if (!short_name) {
820 rtn = ast_malloc(len + 1);
821 if (rtn) {
822 strcpy(rtn, buffer); /* Safe */
823 }
824 return rtn;
825 }
826
827 search_len = strlen(short_name) + 1;
828 rc = ast_asprintf(&search, "%s=", short_name);
829 if (rc != search_len) {
830 return NULL;
831 }
832
833 search_buff = buffer;
834 while((line = ast_read_line_from_buffer(&search_buff))) {
835 if (ast_begins_with(line, search)) {
836 rtn = ast_malloc(strlen(line) - search_len + 1);
837 if (rtn) {
838 strcpy(rtn, line + search_len); /* Safe */
839 }
840 break;
841 }
842 }
843
844 ast_std_free(search);
845 return rtn;
846}
void ast_std_free(void *ptr)
Definition: astmm.c:1734
#define ast_asprintf(ret, fmt,...)
A wrapper for asprintf()
Definition: astmm.h:267
#define ast_malloc(len)
A wrapper for malloc()
Definition: astmm.h:191
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
char * ast_read_line_from_buffer(char **buffer)
Read lines from a string buffer.
Definition: strings.c:371
static int force_inline attribute_pure ast_begins_with(const char *str, const char *prefix)
Checks whether a string begins with another.
Definition: strings.h:97

References ast_asprintf, ast_begins_with(), ast_malloc, ast_read_line_from_buffer(), ast_std_free(), len(), NULL, and RAII_VAR.

Referenced by check_cert().

◆ crypto_get_raw_pubkey_from_cert()

int crypto_get_raw_pubkey_from_cert ( X509 *  cert,
unsigned char **  raw_key 
)

Retrieve RAW public key from cert.

Parameters
certThe cert containing the extension
raw_keyAddress of char * to place the raw key. Must be freed with ast_free after use
Return values
<=0An error has occurred
>0Length of raw key

Definition at line 307 of file crypto_utils.c.

309{
310 RAII_VAR(EVP_PKEY *, public_key, X509_get_pubkey(cert), EVP_PKEY_free);
311
312 if (!public_key) {
313 crypto_log_openssl(LOG_ERROR, "Unable to retrieve pubkey from cert\n");
314 return -1;
315 }
316
317 return crypto_extract_raw_pubkey(public_key, buffer);
318}
int crypto_extract_raw_pubkey(EVP_PKEY *key, unsigned char **buffer)
Extract raw public key from EVP_PKEY.
Definition: crypto_utils.c:293

References crypto_extract_raw_pubkey(), crypto_log_openssl(), LOG_ERROR, and RAII_VAR.

Referenced by check_cert().

◆ crypto_has_private_key_from_memory()

int crypto_has_private_key_from_memory ( const char *  buffer,
size_t  size 
)

Check if the supplied buffer has a private key.

Note
This function can be used to check a certificate PEM file to see if it also has a private key in it.
Parameters
bufferarbitrary buffer
sizebuffer size
Return values
1buffer has a private key
0buffer does not have a private key

Definition at line 266 of file crypto_utils.c.

267{
268 RAII_VAR(EVP_PKEY *, key, load_private_key_from_memory(buffer, size), EVP_PKEY_free);
269
270 return key ? 1 : 0;
271}
static EVP_PKEY * load_private_key_from_memory(const char *buffer, size_t size)
Definition: crypto_utils.c:236

References load_private_key_from_memory(), and RAII_VAR.

Referenced by as_check_common_config().

◆ crypto_is_cert_time_valid()

int crypto_is_cert_time_valid ( X509 *  cert,
time_t  reftime 
)

Check if the reftime is within the cert's valid dates.

Parameters
certThe cert to check
reftimeto use or 0 to use current time
Return values
1Cert is valid
0Cert is not valid

Definition at line 721 of file crypto_utils.c.

722{
723 ASN1_STRING *notbefore;
724 ASN1_STRING *notafter;
725
726 if (!reftime) {
727 reftime = time(NULL);
728 }
729 notbefore = X509_get_notBefore(cert);
730 notafter = X509_get_notAfter(cert);
731 if (!notbefore || !notafter) {
732 ast_log(LOG_ERROR, "Either notbefore or notafter were not present in the cert\n");
733 return 0;
734 }
735
736 return (X509_cmp_time(notbefore, &reftime) < 0 &&
737 X509_cmp_time(notafter, &reftime) > 0);
738}

References ast_log, LOG_ERROR, and NULL.

Referenced by as_check_common_config(), and check_cert().

◆ crypto_is_cert_trusted()

int crypto_is_cert_trusted ( struct crypto_cert_store store,
X509 *  cert,
const char **  err_msg 
)

Check if the cert is trusted.

Parameters
storeThe CA store to check against
certThe cert to check
err_msgOptional pointer to a const char *
Return values
1Cert is trusted
0Cert is not trusted

Definition at line 740 of file crypto_utils.c.

741{
742 X509_STORE_CTX *verify_ctx = NULL;
743 int rc = 0;
744
745 if (!(verify_ctx = X509_STORE_CTX_new())) {
746 crypto_log_openssl(LOG_ERROR, "Unable to create verify_ctx\n");
747 return 0;
748 }
749
750 if (X509_STORE_CTX_init(verify_ctx, store->certs, cert, store->untrusted_stack) != 1) {
751 X509_STORE_CTX_cleanup(verify_ctx);
752 X509_STORE_CTX_free(verify_ctx);
753 crypto_log_openssl(LOG_ERROR, "Unable to initialize verify_ctx\n");
754 return 0;
755 }
756 X509_STORE_CTX_set0_crls(verify_ctx, store->crl_stack);
757
758 rc = X509_verify_cert(verify_ctx);
759 if (rc != 1 && err_msg != NULL) {
760 int err = X509_STORE_CTX_get_error(verify_ctx);
761 *err_msg = X509_verify_cert_error_string(err);
762 }
763 X509_STORE_CTX_cleanup(verify_ctx);
764 X509_STORE_CTX_free(verify_ctx);
765
766 return rc;
767}

References crypto_log_openssl(), LOG_ERROR, NULL, and pem_file_cb_data::store.

Referenced by check_cert(), and cli_verify_cert().

◆ crypto_load()

int crypto_load ( void  )

Initialize the crypto utils.

Definition at line 848 of file crypto_utils.c.

849{
851}
@ AST_MODULE_LOAD_SUCCESS
Definition: module.h:70

References AST_MODULE_LOAD_SUCCESS.

◆ crypto_load_cert_from_file()

X509 * crypto_load_cert_from_file ( const char *  filename)

Load an X509 Cert from a file.

Parameters
filenamePEM file
Returns
X509* or NULL on error

Definition at line 189 of file crypto_utils.c.

190{
191 FILE *fp;
192 X509 *cert = NULL;
193
194 if (ast_strlen_zero(filename)) {
195 ast_log(LOG_ERROR, "filename was null or empty\n");
196 return NULL;
197 }
198
199 fp = fopen(filename, "r");
200 if (!fp) {
201 ast_log(LOG_ERROR, "Failed to open %s: %s\n", filename, strerror(errno));
202 return NULL;
203 }
204
205 cert = PEM_read_X509(fp, &cert, NULL, NULL);
206 fclose(fp);
207 if (!cert) {
208 crypto_log_openssl(LOG_ERROR, "Failed to create cert from %s\n", filename);
209 }
210 return cert;
211}
int errno
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:65

References ast_log, ast_strlen_zero(), crypto_log_openssl(), errno, LOG_ERROR, and NULL.

Referenced by cli_verify_cert(), crypto_load_store_from_cert_file(), and retrieve_cert_from_cache().

◆ crypto_load_cert_from_memory()

X509 * crypto_load_cert_from_memory ( const char *  buffer,
size_t  size 
)

Load an X509 Cert from a NULL terminated buffer.

Parameters
buffercontaining the cert
sizesize of the buffer. May be -1 if the buffer is NULL terminated.
Returns
X509* or NULL on error

Definition at line 213 of file crypto_utils.c.

214{
215 RAII_VAR(BIO *, bio, NULL, BIO_free_all);
216 X509 *cert = NULL;
217
218 if (ast_strlen_zero(buffer) || size <= 0) {
219 ast_log(LOG_ERROR, "buffer was null or empty\n");
220 return NULL;
221 }
222
223 bio = BIO_new_mem_buf(buffer, size);
224 if (!bio) {
225 crypto_log_openssl(LOG_ERROR, "Unable to create memory BIO\n");
226 return NULL;
227 }
228
229 cert = PEM_read_bio_X509(bio, NULL, NULL, NULL);
230 if (!cert) {
231 crypto_log_openssl(LOG_ERROR, "Failed to create cert from BIO\n");
232 }
233 return cert;
234}

References ast_log, ast_strlen_zero(), crypto_log_openssl(), LOG_ERROR, NULL, and RAII_VAR.

Referenced by as_check_common_config(), and retrieve_cert_from_url().

◆ crypto_load_cert_store()

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.

Parameters
storeX509 Store to load
fileCertificate or CRL file to load or NULL
pathPath to directory with hashed certs or CRLs to load or NULL
Note
At least 1 file or path must be specified.
Return values
<=0 failure
0success

Definition at line 563 of file crypto_utils.c.

565{
566 if (ast_strlen_zero(file) && ast_strlen_zero(path)) {
567 ast_log(LOG_ERROR, "Both file and path can't be NULL\n");
568 return -1;
569 }
570
571 if (!store || !store->certs) {
572 ast_log(LOG_ERROR, "store or store->certs is NULL\n");
573 return -1;
574 }
575
576 return _crypto_load_cert_store(store->certs, file, path);
577}
static int _crypto_load_cert_store(X509_STORE *store, const char *file, const char *path)
Definition: crypto_utils.c:521

References _crypto_load_cert_store(), ast_log, ast_strlen_zero(), make_ari_stubs::file, LOG_ERROR, and pem_file_cb_data::store.

Referenced by vs_check_common_config().

◆ crypto_load_crl_from_file()

X509_CRL * crypto_load_crl_from_file ( const char *  filename)

Load an X509 CRL from a PEM file.

Parameters
filenamePEM file
Returns
X509_CRL* or NULL on error

Definition at line 165 of file crypto_utils.c.

166{
167 FILE *fp;
168 X509_CRL *crl = NULL;
169
170 if (ast_strlen_zero(filename)) {
171 ast_log(LOG_ERROR, "filename was null or empty\n");
172 return NULL;
173 }
174
175 fp = fopen(filename, "r");
176 if (!fp) {
177 ast_log(LOG_ERROR, "Failed to open %s: %s\n", filename, strerror(errno));
178 return NULL;
179 }
180
181 crl = PEM_read_X509_CRL(fp, &crl, NULL, NULL);
182 fclose(fp);
183 if (!crl) {
184 crypto_log_openssl(LOG_ERROR, "Failed to create CRL from %s\n", filename);
185 }
186 return crl;
187}

References ast_log, ast_strlen_zero(), crypto_log_openssl(), errno, LOG_ERROR, and NULL.

Referenced by crypto_load_store_from_crl_file().

◆ crypto_load_crl_store()

int crypto_load_crl_store ( struct crypto_cert_store store,
const char *  file,
const char *  path 
)

Load an X509 Store with certificate revocation lists.

Parameters
storeX509 Store to load
fileCRL file to load or NULL
pathPath to directory with hashed CRLs to load or NULL
Note
At least 1 file or path must be specified.
Return values
<=0 failure
0success

Definition at line 622 of file crypto_utils.c.

624{
625 int rc = 0;
626 STACK_OF(X509_OBJECT) *objs = NULL;
627 int count = 0;
628 int i = 0;
629
630 if (ast_strlen_zero(file) && ast_strlen_zero(path)) {
631 ast_log(LOG_ERROR, "Both file and path can't be NULL\n");
632 return -1;
633 }
634
635 if (!store || !store->untrusted || !store->untrusted_stack) {
636 ast_log(LOG_ERROR, "store wasn't initialized properly\n");
637 return -1;
638 }
639
640 rc = _crypto_load_crl_store(store->crls, file, path);
641 if (rc != 0) {
642 return rc;
643 }
644
645 /*
646 * We need to extract the CRLs from the store and push them onto the
647 * crl stack. This is because the verification context needs
648 * a stack of CRLs and not the store.
649 * The store holds the references to the CRLs so we can't
650 * free it.
651 */
652 objs = X509_STORE_get0_objects(store->crls);
653 count = sk_X509_OBJECT_num(objs);
654 for (i = 0; i < count ; i++) {
655 X509_OBJECT *o = sk_X509_OBJECT_value(objs, i);
656 if (X509_OBJECT_get_type(o) == X509_LU_CRL) {
657 X509_CRL *c = X509_OBJECT_get0_X509_CRL(o);
658 sk_X509_CRL_push(store->crl_stack, c);
659 }
660 }
661
662 return 0;
663}
static int _crypto_load_crl_store(X509_STORE *store, const char *file, const char *path)
Definition: crypto_utils.c:542
static struct test_val c

References _crypto_load_crl_store(), ast_log, ast_strlen_zero(), c, make_ari_stubs::file, LOG_ERROR, NULL, and pem_file_cb_data::store.

Referenced by vs_check_common_config().

◆ crypto_load_private_key_from_memory()

EVP_PKEY * crypto_load_private_key_from_memory ( const char *  buffer,
size_t  size 
)

Load a private key from memory.

Parameters
bufferprivate key
sizebuffer size
Returns
EVP_PKEY* or NULL on error

Definition at line 257 of file crypto_utils.c.

258{
259 EVP_PKEY *key = load_private_key_from_memory(buffer, size);
260 if (!key) {
261 crypto_log_openssl(LOG_ERROR, "Unable to load private key from memory\n");
262 }
263 return key;
264}

References crypto_log_openssl(), load_private_key_from_memory(), and LOG_ERROR.

◆ crypto_load_privkey_from_file()

EVP_PKEY * crypto_load_privkey_from_file ( const char *  filename)

Load a private key from a file.

Parameters
filenameFile to load from
Returns
EVP_PKEY *key or NULL on error

Definition at line 141 of file crypto_utils.c.

142{
143 EVP_PKEY *key = NULL;
144 FILE *fp;
145
146 if (ast_strlen_zero(filename)) {
147 ast_log(LOG_ERROR, "filename was null or empty\n");
148 return NULL;
149 }
150
151 fp = fopen(filename, "r");
152 if (!fp) {
153 ast_log(LOG_ERROR, "Failed to open %s: %s\n", filename, strerror(errno));
154 return NULL;
155 }
156
157 key = PEM_read_PrivateKey(fp, NULL, NULL, NULL);
158 fclose(fp);
159 if (!key) {
160 crypto_log_openssl(LOG_ERROR, "Failed to load private key from %s\n", filename);
161 }
162 return key;
163}

References ast_log, ast_strlen_zero(), crypto_log_openssl(), errno, LOG_ERROR, and NULL.

Referenced by as_check_common_config().

◆ crypto_load_untrusted_cert_store()

int crypto_load_untrusted_cert_store ( struct crypto_cert_store store,
const char *  file,
const char *  path 
)

Load an X509 Store with untrusted certificates.

Parameters
storeX509 Store to load
fileCertificate file to load or NULL
pathPath to directory with hashed certs to load or NULL
Note
At least 1 file or path must be specified.
Return values
<=0 failure
0success

Definition at line 579 of file crypto_utils.c.

581{
582 int rc = 0;
583 STACK_OF(X509_OBJECT) *objs = NULL;
584 int count = 0;
585 int i = 0;
586
587 if (ast_strlen_zero(file) && ast_strlen_zero(path)) {
588 ast_log(LOG_ERROR, "Both file and path can't be NULL\n");
589 return -1;
590 }
591
592 if (!store || !store->untrusted || !store->untrusted_stack) {
593 ast_log(LOG_ERROR, "store wasn't initialized properly\n");
594 return -1;
595 }
596
597 rc = _crypto_load_cert_store(store->untrusted, file, path);
598 if (rc != 0) {
599 return rc;
600 }
601
602 /*
603 * We need to extract the certs from the store and push them onto the
604 * untrusted stack. This is because the verification context needs
605 * a stack of untrusted certs and not the store.
606 * The store holds the references to the certs so we can't
607 * free it.
608 */
609 objs = X509_STORE_get0_objects(store->untrusted);
610 count = sk_X509_OBJECT_num(objs);
611 for (i = 0; i < count ; i++) {
612 X509_OBJECT *o = sk_X509_OBJECT_value(objs, i);
613 if (X509_OBJECT_get_type(o) == X509_LU_X509) {
614 X509 *c = X509_OBJECT_get0_X509(o);
615 sk_X509_push(store->untrusted_stack, c);
616 }
617 }
618
619 return 0;
620}

References _crypto_load_cert_store(), ast_log, ast_strlen_zero(), c, make_ari_stubs::file, LOG_ERROR, NULL, and pem_file_cb_data::store.

Referenced by vs_check_common_config().

◆ crypto_log_openssl()

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.

Parameters
levelType of log event
fileWill be provided by the AST_LOG_* macro
lineWill be provided by the AST_LOG_* macro
functionWill be provided by the AST_LOG_* macro
fmtThis is what is important. The format is the same as your favorite breed of printf. You know how that works, right? :-)

Definition at line 45 of file crypto_utils.c.

47{
48 FILE *fp;
49 char *buffer;
50 size_t length;
51 va_list ap;
52 char *tmp_fmt;
53
54 fp = open_memstream(&buffer, &length);
55 if (!fp) {
56 return;
57 }
58
59 va_start(ap, fmt);
60 if (!ast_strlen_zero(fmt)) {
61 size_t fmt_len = strlen(fmt);
62 if (fmt[fmt_len - 1] == '\n') {
63 tmp_fmt = ast_strdupa(fmt);
64 tmp_fmt[fmt_len - 1] = '\0';
65 fmt = tmp_fmt;
66 }
67 }
68 vfprintf(fp, fmt, ap);
69 fputs(": ", fp);
70 ERR_print_errors_fp(fp);
71 fclose(fp);
72
73 if (length) {
74 ast_log(level, file, line, function, "%s\n", buffer);
75 }
76
77 ast_std_free(buffer);
78}
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:298

References ast_log, ast_std_free(), ast_strdupa, ast_strlen_zero(), and make_ari_stubs::file.

Referenced by check_tn_auth_list(), crypto_asn_time_as_time_t(), crypto_create_cert_store(), crypto_extract_raw_privkey(), crypto_extract_raw_pubkey(), crypto_get_raw_pubkey_from_cert(), crypto_is_cert_trusted(), crypto_load_cert_from_file(), crypto_load_cert_from_memory(), crypto_load_crl_from_file(), crypto_load_private_key_from_memory(), crypto_load_privkey_from_file(), crypto_load_store_from_cert_file(), crypto_load_store_from_crl_file(), crypto_register_x509_extension(), dump_mem_bio(), and load_private_key_from_memory().

◆ crypto_register_x509_extension()

int crypto_register_x509_extension ( const char *  oid,
const char *  short_name,
const char *  long_name 
)

Register a certificate extension to openssl.

Parameters
oidThe OID of the extension
short_nameThe short name of the extension
long_nameThe long name of the extension
Return values
<0Extension was not successfully added
>=NID of the added extension

Definition at line 80 of file crypto_utils.c.

82{
83 int nid = 0;
84
85 if (ast_strlen_zero(oid) || ast_strlen_zero(short_name) ||
86 ast_strlen_zero(long_name)) {
87 ast_log(LOG_ERROR, "One or more of oid, short_name or long_name are NULL or empty\n");
88 return -1;
89 }
90
91 nid = OBJ_sn2nid(short_name);
92 if (nid != NID_undef) {
93 ast_log(LOG_NOTICE, "NID %d, object %s already registered\n", nid, short_name);
94 return nid;
95 }
96
97 nid = OBJ_create(oid, short_name, long_name);
98 if (nid == NID_undef) {
99 crypto_log_openssl(LOG_ERROR, "Couldn't register %s X509 extension\n", short_name);
100 return -1;
101 }
102 ast_log(LOG_NOTICE, "Registered object %s as NID %d\n", short_name, nid);
103
104 return nid;
105}
#define LOG_NOTICE

References ast_log, ast_strlen_zero(), crypto_log_openssl(), LOG_ERROR, and LOG_NOTICE.

Referenced by load_module().

◆ crypto_show_cli_store()

int crypto_show_cli_store ( struct crypto_cert_store store,
int  fd 
)

Dump a cert store to the asterisk CLI.

Parameters
storeX509 Store to dump
fdThe CLI fd to print to
Return values
Countof objects printed

Definition at line 665 of file crypto_utils.c.

666{
667#if (OPENSSL_VERSION_NUMBER >= 0x10100000L)
668 STACK_OF(X509_OBJECT) *objs = NULL;
669 int count = 0;
670 int untrusted_count = 0;
671 int crl_count = 0;
672 int i = 0;
673 char subj[1024];
674
675 /*
676 * The CA certificates are stored in the certs store.
677 */
678 objs = X509_STORE_get0_objects(store->certs);
679 count = sk_X509_OBJECT_num(objs);
680
681 for (i = 0; i < count ; i++) {
682 X509_OBJECT *o = sk_X509_OBJECT_value(objs, i);
683 if (X509_OBJECT_get_type(o) == X509_LU_X509) {
684 X509 *c = X509_OBJECT_get0_X509(o);
685 X509_NAME_oneline(X509_get_subject_name(c), subj, 1024);
686 ast_cli(fd, "Cert: %s\n", subj);
687 } else {
688 ast_log(LOG_ERROR, "CRLs are not allowed in the CA cert store\n");
689 }
690 }
691
692 /*
693 * Although the untrusted certs are stored in the untrusted store,
694 * we already have the stack of certificates so we can just
695 * list them directly.
696 */
697 untrusted_count = sk_X509_num(store->untrusted_stack);
698 for (i = 0; i < untrusted_count ; i++) {
699 X509 *c = sk_X509_value(store->untrusted_stack, i);
700 X509_NAME_oneline(X509_get_subject_name(c), subj, 1024);
701 ast_cli(fd, "Untrusted: %s\n", subj);
702 }
703
704 /*
705 * Same for the CRLs.
706 */
707 crl_count = sk_X509_CRL_num(store->crl_stack);
708 for (i = 0; i < crl_count ; i++) {
709 X509_CRL *crl = sk_X509_CRL_value(store->crl_stack, i);
710 X509_NAME_oneline(X509_CRL_get_issuer(crl), subj, 1024);
711 ast_cli(fd, "CRL: %s\n", subj);
712 }
713
714 return count + untrusted_count + crl_count;
715#else
716 ast_cli(fd, "This command is not supported until OpenSSL 1.1.0\n");
717 return 0;
718#endif
719}
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6

References ast_cli(), ast_log, c, LOG_ERROR, NULL, and pem_file_cb_data::store.

◆ crypto_unload()

int crypto_unload ( void  )

Clean up the crypto utils.

Definition at line 853 of file crypto_utils.c.

854{
855 return 0;
856}

Referenced by unload_module().