Asterisk - The Open Source Telephony Project GIT-master-f3e88d3
Macros | Functions
crypto_utils.c File Reference
#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/logger.h"
#include "asterisk/module.h"
#include "asterisk/stringfields.h"
#include "asterisk/utils.h"
#include "asterisk/vector.h"
#include "asterisk/cli.h"
Include dependency graph for crypto_utils.c:

Go to the source code of this file.

Macros

#define SECS_PER_DAY   86400
 

Functions

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, 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...
 
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...
 
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)
 

Macro Definition Documentation

◆ SECS_PER_DAY

#define SECS_PER_DAY   86400

Definition at line 430 of file crypto_utils.c.

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

432{
433 int pday;
434 int psec;
435 time_t rt = time(NULL);
436
437 if (!ASN1_TIME_diff(&pday, &psec, NULL, at)) {
438 crypto_log_openssl(LOG_ERROR, "Unable to calculate time diff\n");
439 return 0;
440 }
441
442 rt += ((pday * SECS_PER_DAY) + psec);
443
444 return rt;
445}
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
#define SECS_PER_DAY
Definition: crypto_utils.c:430
#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 306 of file crypto_utils.c.

307{
308 struct crypto_cert_store *store = obj;
309
310 if (store->store) {
311 X509_STORE_free(store->store);
312 }
313}
ao2 object wrapper for X509_STORE that provides locking and refcounting
Definition: crypto_utils.h:170
X509_STORE * store
Definition: crypto_utils.h:171

References crypto_cert_store::store.

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

316{
318 if (!store) {
319 ast_log(LOG_ERROR, "Failed to create crypto_cert_store\n");
320 return NULL;
321 }
322 store->store = X509_STORE_new();
323
324 if (!store->store) {
325 crypto_log_openssl(LOG_ERROR, "Failed to create X509_STORE\n");
326 ao2_ref(store, -1);
327 return NULL;
328 }
329
330 return store;
331}
#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:306

References ao2_alloc, ao2_ref, ast_log, crypto_cert_store_destructor(), crypto_log_openssl(), LOG_ERROR, NULL, and crypto_cert_store::store.

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

293{
294 RAII_VAR(BIO *, bio, NULL, BIO_free_all);
295
296 bio = BIO_new(BIO_s_mem());
297
298 if (!bio || (PEM_write_bio_PrivateKey(bio, key, NULL, NULL, 0, NULL, NULL) <= 0)) {
299 crypto_log_openssl(LOG_ERROR, "Unable to write privkey to BIO\n");
300 return -1;
301 }
302
303 return dump_mem_bio(bio, buffer);
304}
static int dump_mem_bio(BIO *bio, unsigned char **buffer)
Definition: crypto_utils.c:245
#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 265 of file crypto_utils.c.

266{
267 RAII_VAR(BIO *, bio, NULL, BIO_free_all);
268
269 bio = BIO_new(BIO_s_mem());
270
271 if (!bio || (PEM_write_bio_PUBKEY(bio, key) <= 0)) {
272 crypto_log_openssl(LOG_ERROR, "Unable to write pubkey to BIO\n");
273 return -1;
274 }
275
276 return dump_mem_bio(bio, buffer);
277}

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

105{
106 int ex_idx;
107 X509_EXTENSION *ex;
108
109 if (nid <= 0) {
110 nid = OBJ_sn2nid(short_name);
111 if (nid == NID_undef) {
112 ast_log(LOG_ERROR, "Extension object for %s not found\n", short_name);
113 return NULL;
114 }
115 } else {
116 const char *tmp = OBJ_nid2sn(nid);
117 if (!tmp) {
118 ast_log(LOG_ERROR, "Extension object for NID %d not found\n", nid);
119 return NULL;
120 }
121 }
122
123 ex_idx = X509_get_ext_by_NID(cert, nid, -1);
124 if (ex_idx < 0) {
125 ast_log(LOG_ERROR, "Extension index not found in certificate\n");
126 return NULL;
127 }
128 ex = X509_get_ext(cert, ex_idx);
129 if (!ex) {
130 ast_log(LOG_ERROR, "Extension not found in certificate\n");
131 return NULL;
132 }
133
134 return X509_EXTENSION_get_data(ex);
135}
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 448 of file crypto_utils.c.

449{
450 size_t len = 0;
451 RAII_VAR(char *, buffer, NULL, ast_std_free);
452 char *search_buff = NULL;
453 char *search = NULL;
454 size_t search_len = 0;
455 char *rtn = NULL;
456 char *line = NULL;
457 /*
458 * If short_name was supplied, we want a multiline subject
459 * with each component on a separate line. This makes it easier
460 * to iterate over the components to find the one we want.
461 * Otherwise, we just want the whole subject on one line.
462 */
463 unsigned long flags =
464 short_name ? XN_FLAG_FN_SN | XN_FLAG_SEP_MULTILINE : XN_FLAG_ONELINE;
465 FILE *fp = open_memstream(&buffer, &len);
466 BIO *bio = fp ? BIO_new_fp(fp, BIO_CLOSE) : NULL;
467 X509_NAME *subject = X509_get_subject_name(cert);
468 int rc = 0;
469
470 if (!fp || !bio || !subject) {
471 return NULL;
472 }
473
474 rc = X509_NAME_print_ex(bio, subject, 0, flags);
475 BIO_free(bio);
476 if (rc < 0) {
477 return NULL;
478 }
479
480 if (!short_name) {
481 rtn = ast_malloc(len + 1);
482 if (rtn) {
483 strcpy(rtn, buffer); /* Safe */
484 }
485 return rtn;
486 }
487
488 search_len = strlen(short_name) + 1;
489 rc = ast_asprintf(&search, "%s=", short_name);
490 if (rc != search_len) {
491 return NULL;
492 }
493
494 search_buff = buffer;
495 while((line = ast_read_line_from_buffer(&search_buff))) {
496 if (ast_begins_with(line, search)) {
497 rtn = ast_malloc(strlen(line) - search_len + 1);
498 if (rtn) {
499 strcpy(rtn, line + search_len); /* Safe */
500 }
501 break;
502 }
503 }
504
505 ast_std_free(search);
506 return rtn;
507}
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 279 of file crypto_utils.c.

281{
282 RAII_VAR(EVP_PKEY *, public_key, X509_get_pubkey(cert), EVP_PKEY_free);
283
284 if (!public_key) {
285 crypto_log_openssl(LOG_ERROR, "Unable to retrieve pubkey from cert\n");
286 return -1;
287 }
288
289 return crypto_extract_raw_pubkey(public_key, buffer);
290}
int crypto_extract_raw_pubkey(EVP_PKEY *key, unsigned char **buffer)
Extract raw public key from EVP_PKEY.
Definition: crypto_utils.c:265

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

239{
240 RAII_VAR(EVP_PKEY *, key, load_private_key_from_memory(buffer, size), EVP_PKEY_free);
241
242 return key ? 1 : 0;
243}
static EVP_PKEY * load_private_key_from_memory(const char *buffer, size_t size)
Definition: crypto_utils.c:208

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

384{
385 ASN1_STRING *notbefore;
386 ASN1_STRING *notafter;
387
388 if (!reftime) {
389 reftime = time(NULL);
390 }
391 notbefore = X509_get_notBefore(cert);
392 notafter = X509_get_notAfter(cert);
393 if (!notbefore || !notafter) {
394 ast_log(LOG_ERROR, "Either notbefore or notafter were not present in the cert\n");
395 return 0;
396 }
397
398 return (X509_cmp_time(notbefore, &reftime) < 0 &&
399 X509_cmp_time(notafter, &reftime) > 0);
400}

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

403{
404 X509_STORE_CTX *verify_ctx = NULL;
405 int rc = 0;
406
407 if (!(verify_ctx = X509_STORE_CTX_new())) {
408 crypto_log_openssl(LOG_ERROR, "Unable to create verify_ctx\n");
409 return 0;
410 }
411
412 if (X509_STORE_CTX_init(verify_ctx, store->store, cert, NULL) != 1) {
413 X509_STORE_CTX_cleanup(verify_ctx);
414 X509_STORE_CTX_free(verify_ctx);
415 crypto_log_openssl(LOG_ERROR, "Unable to initialize verify_ctx\n");
416 return 0;
417 }
418
419 rc = X509_verify_cert(verify_ctx);
420 if (rc != 1 && err_msg != NULL) {
421 int err = X509_STORE_CTX_get_error(verify_ctx);
422 *err_msg = X509_verify_cert_error_string(err);
423 }
424 X509_STORE_CTX_cleanup(verify_ctx);
425 X509_STORE_CTX_free(verify_ctx);
426
427 return rc;
428}

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

Referenced by check_cert().

◆ crypto_load()

int crypto_load ( void  )

Initialize the crypto utils.

Definition at line 509 of file crypto_utils.c.

510{
512}
@ 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 161 of file crypto_utils.c.

162{
163 FILE *fp;
164 X509 *cert = NULL;
165
166 if (ast_strlen_zero(filename)) {
167 ast_log(LOG_ERROR, "filename was null or empty\n");
168 return NULL;
169 }
170
171 fp = fopen(filename, "r");
172 if (!fp) {
173 ast_log(LOG_ERROR, "Failed to open %s: %s\n", filename, strerror(errno));
174 return NULL;
175 }
176
177 cert = PEM_read_X509(fp, &cert, NULL, NULL);
178 fclose(fp);
179 if (!cert) {
180 crypto_log_openssl(LOG_ERROR, "Failed to create cert from %s\n", filename);
181 }
182 return cert;
183}
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 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 185 of file crypto_utils.c.

186{
187 RAII_VAR(BIO *, bio, NULL, BIO_free_all);
188 X509 *cert = NULL;
189
190 if (ast_strlen_zero(buffer) || size <= 0) {
191 ast_log(LOG_ERROR, "buffer was null or empty\n");
192 return NULL;
193 }
194
195 bio = BIO_new_mem_buf(buffer, size);
196 if (!bio) {
197 crypto_log_openssl(LOG_ERROR, "Unable to create memory BIO\n");
198 return NULL;
199 }
200
201 cert = PEM_read_bio_X509(bio, NULL, NULL, NULL);
202 if (!cert) {
203 crypto_log_openssl(LOG_ERROR, "Failed to create cert from BIO\n");
204 }
205 return cert;
206}

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

335{
336 if (ast_strlen_zero(file) && ast_strlen_zero(path)) {
337 ast_log(LOG_ERROR, "Both file and path can't be NULL");
338 return -1;
339 }
340
341 if (!store || !store->store) {
342 ast_log(LOG_ERROR, "store is NULL");
343 return -1;
344 }
345
346 /*
347 * If the file or path are empty strings, we need to pass NULL
348 * so openssl ignores it otherwise it'll try to open a file or
349 * path named ''.
350 */
351 if (!X509_STORE_load_locations(store->store, S_OR(file, NULL), S_OR(path, NULL))) {
352 crypto_log_openssl(LOG_ERROR, "Failed to load store from file '%s' or path '%s'\n",
353 S_OR(file, "N/A"), S_OR(path, "N/A"));
354 return -1;
355 }
356
357 return 0;
358}
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one.
Definition: strings.h:80

References ast_log, ast_strlen_zero(), crypto_log_openssl(), make_ari_stubs::file, LOG_ERROR, NULL, S_OR, and crypto_cert_store::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 229 of file crypto_utils.c.

230{
231 EVP_PKEY *key = load_private_key_from_memory(buffer, size);
232 if (!key) {
233 crypto_log_openssl(LOG_ERROR, "Unable to load private key from memory\n");
234 }
235 return key;
236}

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

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

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

Referenced by as_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 41 of file crypto_utils.c.

43{
44 FILE *fp;
45 char *buffer;
46 size_t length;
47 va_list ap;
48 char *tmp_fmt;
49
50 fp = open_memstream(&buffer, &length);
51 if (!fp) {
52 return;
53 }
54
55 va_start(ap, fmt);
56 if (!ast_strlen_zero(fmt)) {
57 size_t fmt_len = strlen(fmt);
58 if (fmt[fmt_len - 1] == '\n') {
59 tmp_fmt = ast_strdupa(fmt);
60 tmp_fmt[fmt_len - 1] = '\0';
61 fmt = tmp_fmt;
62 }
63 }
64 vfprintf(fp, fmt, ap);
65 fputs(": ", fp);
66 ERR_print_errors_fp(fp);
67 fclose(fp);
68
69 if (length) {
70 ast_log(level, file, line, function, "%s\n", buffer);
71 }
72
73 ast_std_free(buffer);
74}
#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_cert_store(), crypto_load_private_key_from_memory(), crypto_load_privkey_from_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 76 of file crypto_utils.c.

78{
79 int nid = 0;
80
81 if (ast_strlen_zero(oid) || ast_strlen_zero(short_name) ||
82 ast_strlen_zero(long_name)) {
83 ast_log(LOG_ERROR, "One or more of oid, short_name or long_name are NULL or empty\n");
84 return -1;
85 }
86
87 nid = OBJ_sn2nid(short_name);
88 if (nid != NID_undef) {
89 ast_log(LOG_NOTICE, "NID %d, object %s already registered\n", nid, short_name);
90 return nid;
91 }
92
93 nid = OBJ_create(oid, short_name, long_name);
94 if (nid == NID_undef) {
95 crypto_log_openssl(LOG_ERROR, "Couldn't register %s X509 extension\n", short_name);
96 return -1;
97 }
98 ast_log(LOG_NOTICE, "Registered object %s as NID %d\n", short_name, nid);
99
100 return nid;
101}
#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 360 of file crypto_utils.c.

361{
362#if (OPENSSL_VERSION_NUMBER >= 0x10100000L)
363 STACK_OF(X509_OBJECT) *certs = NULL;
364 int count = 0;
365 int i = 0;
366 char subj[1024];
367
368 certs = X509_STORE_get0_objects(store->store);
369 count = sk_X509_OBJECT_num(certs);
370 for (i = 0; i < count ; i++) {
371 X509_OBJECT *o = sk_X509_OBJECT_value(certs, i);
372 X509 *c = X509_OBJECT_get0_X509(o);
373 X509_NAME_oneline(X509_get_subject_name(c), subj, 1024);
374 ast_cli(fd, "%s\n", subj);
375 }
376 return count;
377#else
378 ast_cli(fd, "This command is not supported until OpenSSL 1.1.0\n");
379 return 0;
380#endif
381}
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
static struct test_val c

References ast_cli(), c, NULL, and crypto_cert_store::store.

◆ crypto_unload()

int crypto_unload ( void  )

Clean up the crypto utils.

Definition at line 514 of file crypto_utils.c.

515{
516 return 0;
517}

Referenced by unload_module().

◆ dump_mem_bio()

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

Definition at line 245 of file crypto_utils.c.

246{
247 char *temp_ptr;
248 int raw_key_len;
249
250 raw_key_len = BIO_get_mem_data(bio, &temp_ptr);
251 if (raw_key_len <= 0) {
252 crypto_log_openssl(LOG_ERROR, "Unable to extract raw public key\n");
253 return -1;
254 }
255 *buffer = ast_malloc(raw_key_len);
256 if (!*buffer) {
257 ast_log(LOG_ERROR, "Unable to allocate memory for raw public key\n");
258 return -1;
259 }
260 memcpy(*buffer, temp_ptr, raw_key_len);
261
262 return raw_key_len;
263}

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

209{
210 RAII_VAR(BIO *, bio, NULL, BIO_free_all);
211 EVP_PKEY *key = NULL;
212
213 if (ast_strlen_zero(buffer) || size <= 0) {
214 ast_log(LOG_ERROR, "buffer was null or empty\n");
215 return NULL;
216 }
217
218 bio = BIO_new_mem_buf(buffer, size);
219 if (!bio) {
220 crypto_log_openssl(LOG_ERROR, "Unable to create memory BIO\n");
221 return NULL;
222 }
223
224 key = PEM_read_bio_PrivateKey(bio, NULL, NULL, NULL);
225
226 return key;
227}

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