Asterisk - The Open Source Telephony Project GIT-master-5963e62
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Macros Modules Pages
Data Structures | Macros | Functions
crypto_utils.c File Reference
#include <sys/stat.h>
#include <openssl/err.h>
#include <openssl/ssl.h>
#include <openssl/evp.h>
#include <openssl/md5.h>
#include <openssl/sha.h>
#include <openssl/bio.h>
#include <openssl/obj_mac.h>
#include <openssl/x509.h>
#include <openssl/x509v3.h>
#include <openssl/x509_vfy.h>
#include "crypto_utils.h"
#include "asterisk.h"
#include "asterisk/cli.h"
#include "asterisk/file.h"
#include "asterisk/logger.h"
#include "asterisk/module.h"
#include "asterisk/stringfields.h"
#include "asterisk/utils.h"
#include "asterisk/vector.h"
Include dependency graph for crypto_utils.c:

Go to the source code of this file.

Data Structures

struct  pem_file_cb_data
 

Macros

#define debug_cert_chain(level, cert_chain)
 
#define SECS_PER_DAY   86400
 

Functions

static int _crypto_load_cert_store (X509_STORE *store, const char *file, const char *path)
 
static int _crypto_load_crl_store (X509_STORE *store, const char *file, const char *path)
 
time_t crypto_asn_time_as_time_t (ASN1_TIME *at)
 Return a time_t for an ASN1_TIME. More...
 
static void crypto_cert_store_destructor (void *obj)
 
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 **buffer)
 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, STACK_OF(X509) *cert_chain, const char **err_msg)
 Check if the cert is trusted. More...
 
int crypto_load (void)
 Initialize the crypto utils. More...
 
X509 * crypto_load_cert_chain_from_file (const char *filename, STACK_OF(X509) **cert_chain)
 Load an X509 Cert and any chained certs from a file. More...
 
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. 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...
 
static int crypto_load_store_from_cert_file (X509_STORE *store, const char *file)
 
static int crypto_load_store_from_crl_file (X509_STORE *store, const char *file)
 
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...
 
static int dump_mem_bio (BIO *bio, unsigned char **buffer)
 
static EVP_PKEY * load_private_key_from_memory (const char *buffer, size_t size)
 
static int pem_file_cb (const char *dir_name, const char *filename, void *obj)
 

Macro Definition Documentation

◆ debug_cert_chain

#define debug_cert_chain (   level,
  cert_chain 
)

Definition at line 189 of file crypto_utils.c.

◆ SECS_PER_DAY

#define SECS_PER_DAY   86400

Definition at line 899 of file crypto_utils.c.

Function Documentation

◆ _crypto_load_cert_store()

static int _crypto_load_cert_store ( X509_STORE *  store,
const char *  file,
const char *  path 
)
static

Definition at line 610 of file crypto_utils.c.

611{
612 int rc = 0;
613
614 if (!ast_strlen_zero(file)) {
616 if (rc != 0) {
617 return -1;
618 }
619 }
620
621 if (!ast_strlen_zero(path)) {
622 struct pem_file_cb_data data = { .store = store, .is_crl = 0 };
623 if (ast_file_read_dirs(path, pem_file_cb, &data, 0)) {
624 return -1;
625 }
626 }
627
628 return 0;
629}
static int pem_file_cb(const char *dir_name, const char *filename, void *obj)
Definition: crypto_utils.c:576
static int crypto_load_store_from_cert_file(X509_STORE *store, const char *file)
Definition: crypto_utils.c:523
int ast_file_read_dirs(const char *dir_name, ast_file_on_file on_file, void *obj, int max_depth)
Recursively iterate through files and directories up to max_depth.
Definition: file.c:1282
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:65
X509_STORE * store
Definition: crypto_utils.c:572

References ast_file_read_dirs(), ast_strlen_zero(), crypto_load_store_from_cert_file(), make_ari_stubs::file, pem_file_cb(), and pem_file_cb_data::store.

Referenced by crypto_load_cert_store(), and crypto_load_untrusted_cert_store().

◆ _crypto_load_crl_store()

static int _crypto_load_crl_store ( X509_STORE *  store,
const char *  file,
const char *  path 
)
static

Definition at line 631 of file crypto_utils.c.

632{
633 int rc = 0;
634
635 if (!ast_strlen_zero(file)) {
637 if (rc != 0) {
638 return -1;
639 }
640 }
641
642 if (!ast_strlen_zero(path)) {
643 struct pem_file_cb_data data = { .store = store, .is_crl = 1 };
644 if (ast_file_read_dirs(path, pem_file_cb, &data, 0)) {
645 return -1;
646 }
647 }
648
649 return 0;
650}
static int crypto_load_store_from_crl_file(X509_STORE *store, const char *file)
Definition: crypto_utils.c:547

References ast_file_read_dirs(), ast_strlen_zero(), crypto_load_store_from_crl_file(), make_ari_stubs::file, pem_file_cb(), and pem_file_cb_data::store.

Referenced by crypto_load_crl_store().

◆ 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 900 of file crypto_utils.c.

901{
902 int pday;
903 int psec;
904 time_t rt = time(NULL);
905
906 if (!ASN1_TIME_diff(&pday, &psec, NULL, at)) {
907 crypto_log_openssl(LOG_ERROR, "Unable to calculate time diff\n");
908 return 0;
909 }
910
911 rt += ((pday * SECS_PER_DAY) + psec);
912
913 return rt;
914}
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:899
#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_cert_store_destructor()

static void crypto_cert_store_destructor ( void *  obj)
static

Definition at line 458 of file crypto_utils.c.

459{
460 struct crypto_cert_store *store = obj;
461
462 if (store->certs) {
463 X509_STORE_free(store->certs);
464 }
465 if (store->untrusted) {
466 X509_STORE_free(store->untrusted);
467 }
468 if (store->untrusted_stack) {
469 sk_X509_free(store->untrusted_stack);
470 }
471 if (store->crls) {
472 X509_STORE_free(store->crls);
473 }
474 if (store->crl_stack) {
475 sk_X509_CRL_free(store->crl_stack);
476 }
477}
ao2 object wrapper for X509_STORE that provides locking and refcounting
Definition: crypto_utils.h:191
X509_STORE * untrusted
Definition: crypto_utils.h:196
X509_STORE * certs
Definition: crypto_utils.h:192
X509_STORE * crls
Definition: crypto_utils.h:193

References crypto_cert_store::certs, crypto_cert_store::crls, and crypto_cert_store::untrusted.

Referenced by crypto_create_cert_store().

◆ 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 479 of file crypto_utils.c.

480{
481 struct crypto_cert_store *store = ao2_alloc(sizeof(*store), crypto_cert_store_destructor);
482 if (!store) {
483 ast_log(LOG_ERROR, "Failed to create crypto_cert_store\n");
484 return NULL;
485 }
486
487 store->certs = X509_STORE_new();
488 if (!store->certs) {
489 crypto_log_openssl(LOG_ERROR, "Failed to create X509_STORE\n");
490 ao2_ref(store, -1);
491 return NULL;
492 }
493
494 store->untrusted = X509_STORE_new();
495 if (!store->untrusted) {
496 crypto_log_openssl(LOG_ERROR, "Failed to create untrusted X509_STORE\n");
497 ao2_ref(store, -1);
498 return NULL;
499 }
500 store->untrusted_stack = sk_X509_new_null();
501 if (!store->untrusted_stack) {
502 crypto_log_openssl(LOG_ERROR, "Failed to create untrusted stack\n");
503 ao2_ref(store, -1);
504 return NULL;
505 }
506
507 store->crls = X509_STORE_new();
508 if (!store->crls) {
509 crypto_log_openssl(LOG_ERROR, "Failed to create CRL X509_STORE\n");
510 ao2_ref(store, -1);
511 return NULL;
512 }
513 store->crl_stack = sk_X509_CRL_new_null();
514 if (!store->crl_stack) {
515 crypto_log_openssl(LOG_ERROR, "Failed to create CRL stack\n");
516 ao2_ref(store, -1);
517 return NULL;
518 }
519
520 return store;
521}
#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:458

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 409 of file crypto_utils.c.

410{
411 RAII_VAR(BIO *, bio, NULL, BIO_free_all);
412
413 bio = BIO_new(BIO_s_mem());
414
415 if (!bio || (PEM_write_bio_PrivateKey(bio, key, NULL, NULL, 0, NULL, NULL) <= 0)) {
416 crypto_log_openssl(LOG_ERROR, "Unable to write privkey to BIO\n");
417 return -1;
418 }
419
420 return dump_mem_bio(bio, buffer);
421}
static int dump_mem_bio(BIO *bio, unsigned char **buffer)
Definition: crypto_utils.c:362
#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:947

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 382 of file crypto_utils.c.

383{
384 RAII_VAR(BIO *, bio, NULL, BIO_free_all);
385
386 bio = BIO_new(BIO_s_mem());
387
388 if (!bio || (PEM_write_bio_PUBKEY(bio, key) <= 0)) {
389 crypto_log_openssl(LOG_ERROR, "Unable to write pubkey to BIO\n");
390 return -1;
391 }
392
393 return dump_mem_bio(bio, buffer);
394}

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}

References ast_log, LOG_ERROR, and NULL.

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 917 of file crypto_utils.c.

918{
919 size_t len = 0;
920 RAII_VAR(char *, buffer, NULL, ast_std_free);
921 char *search_buff = NULL;
922 char *search = NULL;
923 size_t search_len = 0;
924 char *rtn = NULL;
925 char *line = NULL;
926 /*
927 * If short_name was supplied, we want a multiline subject
928 * with each component on a separate line. This makes it easier
929 * to iterate over the components to find the one we want.
930 * Otherwise, we just want the whole subject on one line.
931 */
932 unsigned long flags =
933 short_name ? XN_FLAG_FN_SN | XN_FLAG_SEP_MULTILINE : XN_FLAG_ONELINE;
934 FILE *fp = open_memstream(&buffer, &len);
935 BIO *bio = fp ? BIO_new_fp(fp, BIO_CLOSE) : NULL;
936 X509_NAME *subject = X509_get_subject_name(cert);
937 int rc = 0;
938
939 if (!fp || !bio || !subject) {
940 return NULL;
941 }
942
943 rc = X509_NAME_print_ex(bio, subject, 0, flags);
944 BIO_free(bio);
945 if (rc < 0) {
946 return NULL;
947 }
948
949 if (!short_name) {
950 rtn = ast_malloc(len + 1);
951 if (rtn) {
952 strcpy(rtn, buffer); /* Safe */
953 }
954 return rtn;
955 }
956
957 search_len = strlen(short_name) + 1;
958 rc = ast_asprintf(&search, "%s=", short_name);
959 if (rc != search_len) {
960 return NULL;
961 }
962
963 search_buff = buffer;
964 while((line = ast_read_line_from_buffer(&search_buff))) {
965 if (ast_begins_with(line, search)) {
966 rtn = ast_malloc(strlen(line) - search_len + 1);
967 if (rtn) {
968 strcpy(rtn, line + search_len); /* Safe */
969 }
970 break;
971 }
972 }
973
974 ast_std_free(search);
975 return rtn;
976}
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:385
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 396 of file crypto_utils.c.

398{
399 RAII_VAR(EVP_PKEY *, public_key, X509_get_pubkey(cert), EVP_PKEY_free);
400
401 if (!public_key) {
402 crypto_log_openssl(LOG_ERROR, "Unable to retrieve pubkey from cert\n");
403 return -1;
404 }
405
406 return crypto_extract_raw_pubkey(public_key, buffer);
407}
int crypto_extract_raw_pubkey(EVP_PKEY *key, unsigned char **buffer)
Extract raw public key from EVP_PKEY.
Definition: crypto_utils.c:382

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 355 of file crypto_utils.c.

356{
357 RAII_VAR(EVP_PKEY *, key, load_private_key_from_memory(buffer, size), EVP_PKEY_free);
358
359 return key ? 1 : 0;
360}
static EVP_PKEY * load_private_key_from_memory(const char *buffer, size_t size)
Definition: crypto_utils.c:325

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 810 of file crypto_utils.c.

811{
812 ASN1_STRING *notbefore;
813 ASN1_STRING *notafter;
814
815 if (!reftime) {
816 reftime = time(NULL);
817 }
818 notbefore = X509_get_notBefore(cert);
819 notafter = X509_get_notAfter(cert);
820 if (!notbefore || !notafter) {
821 ast_log(LOG_ERROR, "Either notbefore or notafter were not present in the cert\n");
822 return 0;
823 }
824
825 return (X509_cmp_time(notbefore, &reftime) < 0 &&
826 X509_cmp_time(notafter, &reftime) > 0);
827}

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,
STACK_OF(X509) *  cert_chain,
const char **  err_msg 
)

Check if the cert is trusted.

Parameters
storeThe CA store to check against
certThe cert to check
cert_chainAn untrusted certificate chain that may have accompanied the cert.
err_msgOptional pointer to a const char *
Return values
1Cert is trusted
0Cert is not trusted

Definition at line 829 of file crypto_utils.c.

831{
832 X509_STORE_CTX *verify_ctx = NULL;
833 RAII_VAR(STACK_OF(X509) *, untrusted_stack, NULL, sk_X509_free);
834 int rc = 0;
835
836 if (!(verify_ctx = X509_STORE_CTX_new())) {
837 crypto_log_openssl(LOG_ERROR, "Unable to create verify_ctx\n");
838 return 0;
839 }
840
841 if (cert_chain && sk_X509_num(cert_chain) > 0) {
842 int untrusted_count = store->untrusted_stack ? sk_X509_num(store->untrusted_stack) : 0;
843 int i = 0;
844
845 untrusted_stack = sk_X509_dup(cert_chain);
846 if (!untrusted_stack) {
847 crypto_log_openssl(LOG_ERROR, "Unable to duplicate untrusted stack\n");
848 X509_STORE_CTX_free(verify_ctx);
849 return 0;
850 }
851 /*
852 * If store->untrusted_stack was NULL for some reason then
853 * untrusted_count will be 0 so the loop will never run.
854 */
855 for (i = 0; i < untrusted_count; i++) {
856 X509 *c = sk_X509_value(store->untrusted_stack, i);
857 if (sk_X509_push(untrusted_stack, c) <= 0) {
858 crypto_log_openssl(LOG_ERROR, "Unable to push untrusted cert onto stack\n");
859 sk_X509_free(untrusted_stack);
860 X509_STORE_CTX_free(verify_ctx);
861 return 0;
862 }
863 }
864 /*
865 * store->untrusted_stack should always be allocated even if empty
866 * but we'll make sure.
867 */
868 } else if (store->untrusted_stack){
869 /* This is a dead simple shallow clone */
870 ast_debug(4, "cert_chain had no certs\n");
871 untrusted_stack = sk_X509_dup(store->untrusted_stack);
872 if (!untrusted_stack) {
873 crypto_log_openssl(LOG_ERROR, "Unable to duplicate untrusted stack\n");
874 X509_STORE_CTX_free(verify_ctx);
875 return 0;
876 }
877 }
878
879 if (X509_STORE_CTX_init(verify_ctx, store->certs, cert, untrusted_stack) != 1) {
880 X509_STORE_CTX_cleanup(verify_ctx);
881 X509_STORE_CTX_free(verify_ctx);
882 crypto_log_openssl(LOG_ERROR, "Unable to initialize verify_ctx\n");
883 return 0;
884 }
885 X509_STORE_CTX_set0_crls(verify_ctx, store->crl_stack);
886
887 rc = X509_verify_cert(verify_ctx);
888 if (rc != 1 && err_msg != NULL) {
889 int err = X509_STORE_CTX_get_error(verify_ctx);
890 *err_msg = X509_verify_cert_error_string(err);
891 }
892
893 X509_STORE_CTX_cleanup(verify_ctx);
894 X509_STORE_CTX_free(verify_ctx);
895
896 return rc;
897}
#define ast_debug(level,...)
Log a DEBUG message.
static struct test_val c

References ast_debug, c, crypto_log_openssl(), LOG_ERROR, NULL, RAII_VAR, 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 978 of file crypto_utils.c.

979{
981}
@ AST_MODULE_LOAD_SUCCESS
Definition: module.h:70

References AST_MODULE_LOAD_SUCCESS.

◆ crypto_load_cert_chain_from_file()

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.

Parameters
filenamePEM file
chain_stackThe address of a STACK_OF(X509) pointer to receive the chain of certificates if any.
Note
The caller is responsible for freeing the cert_chain stack and any certs in it.
Returns
X509* or NULL on error

Definition at line 203 of file crypto_utils.c.

204{
205 FILE *fp;
206 X509 *end_cert = NULL;
207
208 if (ast_strlen_zero(filename)) {
209 ast_log(LOG_ERROR, "filename was null or empty\n");
210 return NULL;
211 }
212
213 fp = fopen(filename, "r");
214 if (!fp) {
215 ast_log(LOG_ERROR, "Failed to open %s: %s\n", filename, strerror(errno));
216 return NULL;
217 }
218
219 end_cert = PEM_read_X509(fp, &end_cert, NULL, NULL);
220 if (!end_cert) {
221 crypto_log_openssl(LOG_ERROR, "Failed to create end_cert from %s\n", filename);
222 fclose(fp);
223 return NULL;
224 }
225
226 /*
227 * If the caller provided a stack, we will read the chain certs
228 * (if any) into it.
229 */
230 if (cert_chain) {
231 X509 *chain_cert = NULL;
232
233 *cert_chain = sk_X509_new_null();
234 while ((chain_cert = PEM_read_X509(fp, &chain_cert, NULL, NULL)) != NULL) {
235 if (sk_X509_push(*cert_chain, chain_cert) <= 0) {
236 crypto_log_openssl(LOG_ERROR, "Failed to add chain cert from %s to list\n",
237 filename);
238 fclose(fp);
239 X509_free(end_cert);
240 sk_X509_pop_free(*cert_chain, X509_free);
241 return NULL;
242 }
243 /* chain_cert needs to be reset to NULL after every call to PEM_read_X509 */
244 chain_cert = NULL;
245 }
246 }
247
248 if (DEBUG_ATLEAST(4)) {
249 char subj[1024];
250
251 X509_NAME_oneline(X509_get_subject_name(end_cert), subj, 1024);
252 ast_debug(4, "Opened end cert '%s' from '%s'\n", subj, filename);
253
254 if (cert_chain && *cert_chain) {
255 debug_cert_chain(4, *cert_chain);
256 } else {
257 ast_debug(4, "No chain certs found in '%s'\n", filename);
258 }
259 }
260
261 fclose(fp);
262
263 return end_cert;
264}
#define debug_cert_chain(level, cert_chain)
Definition: crypto_utils.c:189
#define DEBUG_ATLEAST(level)
int errno

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

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

◆ crypto_load_cert_chain_from_memory()

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.

Parameters
buffercontaining the cert
sizesize of the buffer. May be -1 if the buffer is NULL terminated.
chain_stackThe address of a STACK_OF(X509) pointer to receive the chain of certificates if any.
Note
The caller is responsible for freeing the cert_chain stack and any certs in it.
Returns
X509* or NULL on error

Definition at line 266 of file crypto_utils.c.

268{
269 RAII_VAR(BIO *, bio, NULL, BIO_free_all);
270 X509 *end_cert = NULL;
271
272 if (ast_strlen_zero(buffer) || size <= 0) {
273 ast_log(LOG_ERROR, "buffer was null or empty\n");
274 return NULL;
275 }
276
277 bio = BIO_new_mem_buf(buffer, size);
278 if (!bio) {
279 crypto_log_openssl(LOG_ERROR, "Unable to create memory BIO\n");
280 return NULL;
281 }
282
283 end_cert = PEM_read_bio_X509(bio, NULL, NULL, NULL);
284 if (!end_cert) {
285 crypto_log_openssl(LOG_ERROR, "Failed to create end_cert from BIO\n");
286 return NULL;
287 }
288
289 /*
290 * If the caller provided a stack, we will read the chain certs
291 * (if any) into it.
292 */
293 if (cert_chain) {
294 X509 *chain_cert = NULL;
295
296 *cert_chain = sk_X509_new_null();
297 while ((chain_cert = PEM_read_bio_X509(bio, &chain_cert, NULL, NULL)) != NULL) {
298 if (sk_X509_push(*cert_chain, chain_cert) <= 0) {
299 crypto_log_openssl(LOG_ERROR, "Failed to add chain cert from BIO to list\n");
300 X509_free(end_cert);
301 sk_X509_pop_free(*cert_chain, X509_free);
302 return NULL;
303 }
304 /* chain_cert needs to be reset to NULL after every call to PEM_read_X509 */
305 chain_cert = NULL;
306 }
307 }
308
309 if (DEBUG_ATLEAST(4)) {
310 char subj[1024];
311
312 X509_NAME_oneline(X509_get_subject_name(end_cert), subj, 1024);
313 ast_debug(4, "Opened end cert '%s' from BIO\n", subj);
314
315 if (cert_chain && *cert_chain) {
316 debug_cert_chain(4, *cert_chain);
317 } else {
318 ast_debug(4, "No chain certs found in BIO\n");
319 }
320 }
321
322 return end_cert;
323}

References ast_debug, ast_log, ast_strlen_zero(), crypto_log_openssl(), DEBUG_ATLEAST, debug_cert_chain, 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 652 of file crypto_utils.c.

654{
655 if (ast_strlen_zero(file) && ast_strlen_zero(path)) {
656 ast_log(LOG_ERROR, "Both file and path can't be NULL\n");
657 return -1;
658 }
659
660 if (!store || !store->certs) {
661 ast_log(LOG_ERROR, "store or store->certs is NULL\n");
662 return -1;
663 }
664
665 return _crypto_load_cert_store(store->certs, file, path);
666}
static int _crypto_load_cert_store(X509_STORE *store, const char *file, const char *path)
Definition: crypto_utils.c:610

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 711 of file crypto_utils.c.

713{
714 int rc = 0;
715 STACK_OF(X509_OBJECT) *objs = NULL;
716 int count = 0;
717 int i = 0;
718
719 if (ast_strlen_zero(file) && ast_strlen_zero(path)) {
720 ast_log(LOG_ERROR, "Both file and path can't be NULL\n");
721 return -1;
722 }
723
724 if (!store || !store->untrusted || !store->untrusted_stack) {
725 ast_log(LOG_ERROR, "store wasn't initialized properly\n");
726 return -1;
727 }
728
729 rc = _crypto_load_crl_store(store->crls, file, path);
730 if (rc != 0) {
731 return rc;
732 }
733
734 /*
735 * We need to extract the CRLs from the store and push them onto the
736 * crl stack. This is because the verification context needs
737 * a stack of CRLs and not the store.
738 * The store holds the references to the CRLs so we can't
739 * free it.
740 */
741 objs = X509_STORE_get0_objects(store->crls);
742 count = sk_X509_OBJECT_num(objs);
743 for (i = 0; i < count ; i++) {
744 X509_OBJECT *o = sk_X509_OBJECT_value(objs, i);
745 if (X509_OBJECT_get_type(o) == X509_LU_CRL) {
746 X509_CRL *c = X509_OBJECT_get0_X509_CRL(o);
747 sk_X509_CRL_push(store->crl_stack, c);
748 }
749 }
750
751 return 0;
752}
static int _crypto_load_crl_store(X509_STORE *store, const char *file, const char *path)
Definition: crypto_utils.c:631

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 346 of file crypto_utils.c.

347{
348 EVP_PKEY *key = load_private_key_from_memory(buffer, size);
349 if (!key) {
350 crypto_log_openssl(LOG_ERROR, "Unable to load private key from memory\n");
351 }
352 return key;
353}

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_store_from_cert_file()

static int crypto_load_store_from_cert_file ( X509_STORE *  store,
const char *  file 
)
static

Definition at line 523 of file crypto_utils.c.

524{
525 X509 *cert;
526 int rc = 0;
527
528 if (ast_strlen_zero(file)) {
529 ast_log(LOG_ERROR, "file was null or empty\n");
530 return -1;
531 }
532
534 if (!cert) {
535 return -1;
536 }
537 rc = X509_STORE_add_cert(store, cert);
538 X509_free(cert);
539 if (!rc) {
540 crypto_log_openssl(LOG_ERROR, "Failed to load store from file '%s'\n", file);
541 return -1;
542 }
543
544 return 0;
545}
X509 * crypto_load_cert_chain_from_file(const char *filename, STACK_OF(X509) **cert_chain)
Load an X509 Cert and any chained certs from a file.
Definition: crypto_utils.c:203

References ast_log, ast_strlen_zero(), crypto_load_cert_chain_from_file(), crypto_log_openssl(), make_ari_stubs::file, LOG_ERROR, and NULL.

Referenced by _crypto_load_cert_store(), and pem_file_cb().

◆ crypto_load_store_from_crl_file()

static int crypto_load_store_from_crl_file ( X509_STORE *  store,
const char *  file 
)
static

Definition at line 547 of file crypto_utils.c.

548{
549 X509_CRL *crl;
550 int rc = 0;
551
552 if (ast_strlen_zero(file)) {
553 ast_log(LOG_ERROR, "file was null or empty\n");
554 return -1;
555 }
556
558 if (!crl) {
559 return -1;
560 }
561 rc = X509_STORE_add_crl(store, crl);
562 X509_CRL_free(crl);
563 if (!rc) {
564 crypto_log_openssl(LOG_ERROR, "Failed to load store from file '%s'\n", file);
565 return -1;
566 }
567
568 return 0;
569}
X509_CRL * crypto_load_crl_from_file(const char *filename)
Load an X509 CRL from a PEM file.
Definition: crypto_utils.c:165

References ast_log, ast_strlen_zero(), crypto_load_crl_from_file(), crypto_log_openssl(), make_ari_stubs::file, and LOG_ERROR.

Referenced by _crypto_load_crl_store(), and pem_file_cb().

◆ 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 668 of file crypto_utils.c.

670{
671 int rc = 0;
672 STACK_OF(X509_OBJECT) *objs = NULL;
673 int count = 0;
674 int i = 0;
675
676 if (ast_strlen_zero(file) && ast_strlen_zero(path)) {
677 ast_log(LOG_ERROR, "Both file and path can't be NULL\n");
678 return -1;
679 }
680
681 if (!store || !store->untrusted || !store->untrusted_stack) {
682 ast_log(LOG_ERROR, "store wasn't initialized properly\n");
683 return -1;
684 }
685
686 rc = _crypto_load_cert_store(store->untrusted, file, path);
687 if (rc != 0) {
688 return rc;
689 }
690
691 /*
692 * We need to extract the certs from the store and push them onto the
693 * untrusted stack. This is because the verification context needs
694 * a stack of untrusted certs and not the store.
695 * The store holds the references to the certs so we can't
696 * free it.
697 */
698 objs = X509_STORE_get0_objects(store->untrusted);
699 count = sk_X509_OBJECT_num(objs);
700 for (i = 0; i < count ; i++) {
701 X509_OBJECT *o = sk_X509_OBJECT_value(objs, i);
702 if (X509_OBJECT_get_type(o) == X509_LU_X509) {
703 X509 *c = X509_OBJECT_get0_X509(o);
704 sk_X509_push(store->untrusted_stack, c);
705 }
706 }
707
708 return 0;
709}

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_chain_from_file(), crypto_load_cert_chain_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 754 of file crypto_utils.c.

755{
756#if (OPENSSL_VERSION_NUMBER >= 0x10100000L)
757 STACK_OF(X509_OBJECT) *objs = NULL;
758 int count = 0;
759 int untrusted_count = 0;
760 int crl_count = 0;
761 int i = 0;
762 char subj[1024];
763
764 /*
765 * The CA certificates are stored in the certs store.
766 */
767 objs = X509_STORE_get0_objects(store->certs);
768 count = sk_X509_OBJECT_num(objs);
769
770 for (i = 0; i < count ; i++) {
771 X509_OBJECT *o = sk_X509_OBJECT_value(objs, i);
772 if (X509_OBJECT_get_type(o) == X509_LU_X509) {
773 X509 *c = X509_OBJECT_get0_X509(o);
774 X509_NAME_oneline(X509_get_subject_name(c), subj, 1024);
775 ast_cli(fd, "Cert: %s\n", subj);
776 } else {
777 ast_log(LOG_ERROR, "CRLs are not allowed in the CA cert store\n");
778 }
779 }
780
781 /*
782 * Although the untrusted certs are stored in the untrusted store,
783 * we already have the stack of certificates so we can just
784 * list them directly.
785 */
786 untrusted_count = sk_X509_num(store->untrusted_stack);
787 for (i = 0; i < untrusted_count ; i++) {
788 X509 *c = sk_X509_value(store->untrusted_stack, i);
789 X509_NAME_oneline(X509_get_subject_name(c), subj, 1024);
790 ast_cli(fd, "Untrusted: %s\n", subj);
791 }
792
793 /*
794 * Same for the CRLs.
795 */
796 crl_count = sk_X509_CRL_num(store->crl_stack);
797 for (i = 0; i < crl_count ; i++) {
798 X509_CRL *crl = sk_X509_CRL_value(store->crl_stack, i);
799 X509_NAME_oneline(X509_CRL_get_issuer(crl), subj, 1024);
800 ast_cli(fd, "CRL: %s\n", subj);
801 }
802
803 return count + untrusted_count + crl_count;
804#else
805 ast_cli(fd, "This command is not supported until OpenSSL 1.1.0\n");
806 return 0;
807#endif
808}
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 983 of file crypto_utils.c.

984{
985 return 0;
986}

Referenced by unload_module().

◆ dump_mem_bio()

static int dump_mem_bio ( BIO *  bio,
unsigned char **  buffer 
)
static

Definition at line 362 of file crypto_utils.c.

363{
364 char *temp_ptr;
365 int raw_key_len;
366
367 raw_key_len = BIO_get_mem_data(bio, &temp_ptr);
368 if (raw_key_len <= 0) {
369 crypto_log_openssl(LOG_ERROR, "Unable to extract raw public key\n");
370 return -1;
371 }
372 *buffer = ast_malloc(raw_key_len);
373 if (!*buffer) {
374 ast_log(LOG_ERROR, "Unable to allocate memory for raw public key\n");
375 return -1;
376 }
377 memcpy(*buffer, temp_ptr, raw_key_len);
378
379 return raw_key_len;
380}

References ast_log, ast_malloc, crypto_log_openssl(), and LOG_ERROR.

Referenced by crypto_extract_raw_privkey(), and crypto_extract_raw_pubkey().

◆ load_private_key_from_memory()

static EVP_PKEY * load_private_key_from_memory ( const char *  buffer,
size_t  size 
)
static

Definition at line 325 of file crypto_utils.c.

326{
327 RAII_VAR(BIO *, bio, NULL, BIO_free_all);
328 EVP_PKEY *key = NULL;
329
330 if (ast_strlen_zero(buffer) || size <= 0) {
331 ast_log(LOG_ERROR, "buffer was null or empty\n");
332 return NULL;
333 }
334
335 bio = BIO_new_mem_buf(buffer, size);
336 if (!bio) {
337 crypto_log_openssl(LOG_ERROR, "Unable to create memory BIO\n");
338 return NULL;
339 }
340
341 key = PEM_read_bio_PrivateKey(bio, NULL, NULL, NULL);
342
343 return key;
344}

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

Referenced by crypto_has_private_key_from_memory(), and crypto_load_private_key_from_memory().

◆ pem_file_cb()

static int pem_file_cb ( const char *  dir_name,
const char *  filename,
void *  obj 
)
static

Definition at line 576 of file crypto_utils.c.

577{
578 struct pem_file_cb_data* data = obj;
579 char *filename_merged = NULL;
580 struct stat statbuf;
581 int rc = 0;
582
583 if (ast_asprintf(&filename_merged, "%s/%s", dir_name, filename) < 0) {
584 return -1;
585 }
586
587 if (lstat(filename_merged, &statbuf)) {
588 printf("Error reading path stats - %s: %s\n",
589 filename_merged, strerror(errno));
590 ast_free(filename_merged);
591 return -1;
592 }
593
594 /* We only want the symlinks from the directory */
595 if (!S_ISLNK(statbuf.st_mode)) {
596 ast_free(filename_merged);
597 return 0;
598 }
599
600 if (data->is_crl) {
601 rc = crypto_load_store_from_crl_file(data->store, filename_merged);
602 } else {
603 rc = crypto_load_store_from_cert_file(data->store, filename_merged);
604 }
605
606 ast_free(filename_merged);
607 return rc;
608}
#define ast_free(a)
Definition: astmm.h:180

References ast_asprintf, ast_free, crypto_load_store_from_cert_file(), crypto_load_store_from_crl_file(), errno, pem_file_cb_data::is_crl, NULL, and pem_file_cb_data::store.

Referenced by _crypto_load_cert_store(), and _crypto_load_crl_store().