res_stir_shaken: Fix compilation for CentOS7 (openssl 1.0.2)

* OpenSSL 1.0.2 doesn't support X509_get0_pubkey so we now use
  X509_get_pubkey.  The difference is that X509_get_pubkey requires
  the caller to free the EVP_PKEY themselves so we now let
  RAII_VAR do that.
* OpenSSL 1.0.2 doesn't support upreffing an X509_STORE so we now
  wrap it in an ao2 object.
* OpenSSL 1.0.2 doesn't support X509_STORE_get0_objects to get all
  the certs from an X509_STORE and there's no easy way to polyfill
  it so the CLI commands that list profiles will show a "not
  supported" message instead of listing the certs in a store.

Resolves: #676
pull/796/head
George Joseph 1 year ago
parent 29106567e7
commit 7bbc7b5a3a

@ -351,7 +351,7 @@ struct verification_cfg_common {
enum load_system_certs_enum load_system_certs;
struct ast_acl_list *acl;
X509_STORE *tcs;
struct crypto_cert_store *tcs;
};
#define generate_vcfg_common_sorcery_handlers(object) \

@ -279,10 +279,8 @@ int crypto_extract_raw_pubkey(EVP_PKEY *key, unsigned char **buffer)
int crypto_get_raw_pubkey_from_cert(X509 *cert,
unsigned char **buffer)
{
RAII_VAR(BIO *, bio, NULL, BIO_free_all);
EVP_PKEY *public_key;
RAII_VAR(EVP_PKEY *, public_key, X509_get_pubkey(cert), EVP_PKEY_free);
public_key = X509_get0_pubkey(cert);
if (!public_key) {
crypto_log_openssl(LOG_ERROR, "Unable to retrieve pubkey from cert\n");
return -1;
@ -305,45 +303,34 @@ int crypto_extract_raw_privkey(EVP_PKEY *key, unsigned char **buffer)
return dump_mem_bio(bio, buffer);
}
void crypto_free_cert_store(X509_STORE *store)
static void crypto_cert_store_destructor(void *obj)
{
if (!store) {
return;
}
X509_STORE_free(store);
}
struct crypto_cert_store *store = obj;
int crypto_lock_cert_store(X509_STORE *store)
{
if (!store) {
return -1;
if (store->store) {
X509_STORE_free(store->store);
}
/* lock returns 1 on success */
return X509_STORE_lock(store) == 1 ? 0 : -1;
}
int crypto_unlock_cert_store(X509_STORE *store)
struct crypto_cert_store *crypto_create_cert_store(void)
{
struct crypto_cert_store *store = ao2_alloc(sizeof(*store), crypto_cert_store_destructor);
if (!store) {
return -1;
ast_log(LOG_ERROR, "Failed to create crypto_cert_store\n");
return NULL;
}
/* unlock returns 1 on success */
return X509_STORE_unlock(store) == 1 ? 0 : -1;
}
X509_STORE *crypto_create_cert_store(void)
{
X509_STORE *store = X509_STORE_new();
store->store = X509_STORE_new();
if (!store) {
if (!store->store) {
crypto_log_openssl(LOG_ERROR, "Failed to create X509_STORE\n");
ao2_ref(store, -1);
return NULL;
}
return store;
}
int crypto_load_cert_store(X509_STORE *store, const char *file,
int crypto_load_cert_store(struct crypto_cert_store *store, const char *file,
const char *path)
{
if (ast_strlen_zero(file) && ast_strlen_zero(path)) {
@ -351,7 +338,7 @@ int crypto_load_cert_store(X509_STORE *store, const char *file,
return -1;
}
if (!store) {
if (!store || !store->store) {
ast_log(LOG_ERROR, "store is NULL");
return -1;
}
@ -361,7 +348,7 @@ int crypto_load_cert_store(X509_STORE *store, const char *file,
* so openssl ignores it otherwise it'll try to open a file or
* path named ''.
*/
if (!X509_STORE_load_locations(store, S_OR(file, NULL), S_OR(path, NULL))) {
if (!X509_STORE_load_locations(store->store, S_OR(file, NULL), S_OR(path, NULL))) {
crypto_log_openssl(LOG_ERROR, "Failed to load store from file '%s' or path '%s'\n",
S_OR(file, "N/A"), S_OR(path, "N/A"));
return -1;
@ -370,14 +357,15 @@ int crypto_load_cert_store(X509_STORE *store, const char *file,
return 0;
}
int crypto_show_cli_store(X509_STORE *store, int fd)
int crypto_show_cli_store(struct crypto_cert_store *store, int fd)
{
#if (OPENSSL_VERSION_NUMBER >= 0x10100000L)
STACK_OF(X509_OBJECT) *certs = NULL;
int count = 0;
int i = 0;
char subj[1024];
certs = X509_STORE_get0_objects(store);
certs = X509_STORE_get0_objects(store->store);
count = sk_X509_OBJECT_num(certs);
for (i = 0; i < count ; i++) {
X509_OBJECT *o = sk_X509_OBJECT_value(certs, i);
@ -386,7 +374,12 @@ int crypto_show_cli_store(X509_STORE *store, int fd)
ast_cli(fd, "%s\n", subj);
}
return count;
#else
ast_cli(fd, "This command is not supported until OpenSSL 1.1.0\n");
return 0;
#endif
}
int crypto_is_cert_time_valid(X509*cert, time_t reftime)
{
ASN1_STRING *notbefore;
@ -406,7 +399,7 @@ int crypto_is_cert_time_valid(X509*cert, time_t reftime)
X509_cmp_time(notafter, &reftime) > 0);
}
int crypto_is_cert_trusted(X509_STORE *store, X509 *cert, const char **err_msg)
int crypto_is_cert_trusted(struct crypto_cert_store *store, X509 *cert, const char **err_msg)
{
X509_STORE_CTX *verify_ctx = NULL;
int rc = 0;
@ -416,7 +409,7 @@ int crypto_is_cert_trusted(X509_STORE *store, X509 *cert, const char **err_msg)
return 0;
}
if (X509_STORE_CTX_init(verify_ctx, store, cert, NULL) != 1) {
if (X509_STORE_CTX_init(verify_ctx, store->store, cert, NULL) != 1) {
X509_STORE_CTX_cleanup(verify_ctx);
X509_STORE_CTX_free(verify_ctx);
crypto_log_openssl(LOG_ERROR, "Unable to initialize verify_ctx\n");

@ -164,20 +164,27 @@ int crypto_extract_raw_privkey(EVP_PKEY *key, unsigned char **buffer);
*/
EVP_PKEY *crypto_load_privkey_from_file(const char *filename);
/*!
* \brief ao2 object wrapper for X509_STORE that provides locking and refcounting
*/
struct crypto_cert_store {
X509_STORE *store;
};
/*!
* \brief Free an X509 store
*
* \param store X509 Store to free
*
*/
void crypto_free_cert_store(X509_STORE *store);
#define crypto_free_cert_store(store) ao2_cleanup(store)
/*!
* \brief Create an empty X509 store
*
* \returns X509_STORE* or NULL on error
* \returns crypto_cert_store * or NULL on error
*/
X509_STORE *crypto_create_cert_store(void);
struct crypto_cert_store *crypto_create_cert_store(void);
/*!
* \brief Dump a cert store to the asterisk CLI
@ -187,7 +194,7 @@ X509_STORE *crypto_create_cert_store(void);
* \retval Count of objects printed
*/
int crypto_show_cli_store(X509_STORE *store, int fd);
int crypto_show_cli_store(struct crypto_cert_store *store, int fd);
/*!
* \brief Load an X509 Store with either certificates or CRLs
@ -201,7 +208,7 @@ int crypto_show_cli_store(X509_STORE *store, int fd);
* \retval <= 0 failure
* \retval 0 success
*/
int crypto_load_cert_store(X509_STORE *store, const char *file,
int crypto_load_cert_store(struct crypto_cert_store *store, const char *file,
const char *path);
/*!
@ -212,7 +219,7 @@ int crypto_load_cert_store(X509_STORE *store, const char *file,
* \retval <= 0 failure
* \retval 0 success
*/
int crypto_lock_cert_store(X509_STORE *store);
#define crypto_lock_cert_store(store) ao2_lock(store)
/*!
* \brief Unlocks an X509 Store
@ -222,7 +229,7 @@ int crypto_lock_cert_store(X509_STORE *store);
* \retval <= 0 failure
* \retval 0 success
*/
int crypto_unlock_cert_store(X509_STORE *store);
#define crypto_unlock_cert_store(store) ao2_unlock(store)
/*!
* \brief Check if the reftime is within the cert's valid dates
@ -245,7 +252,7 @@ int crypto_is_cert_time_valid(X509 *cert, time_t reftime);
* \retval 1 Cert is trusted
* \retval 0 Cert is not trusted
*/
int crypto_is_cert_trusted(X509_STORE *store, X509 *cert, const char **err_msg);
int crypto_is_cert_trusted(struct crypto_cert_store *store, X509 *cert, const char **err_msg);
/*!
* \brief Return a time_t for an ASN1_TIME

@ -129,7 +129,7 @@ int vs_copy_cfg_common(const char *id, struct verification_cfg_common *cfg_dst,
cfg_sf_copy_wrapper(id, cfg_dst, cfg_src, ca_path);
cfg_sf_copy_wrapper(id, cfg_dst, cfg_src, crl_file);
cfg_sf_copy_wrapper(id, cfg_dst, cfg_src, crl_path);
X509_STORE_up_ref(cfg_src->tcs);
ao2_bump(cfg_src->tcs);
cfg_dst->tcs = cfg_src->tcs;
}
@ -230,12 +230,12 @@ int vs_check_common_config(const char *id,
if (vcfg_common->tcs) {
if (ENUM_BOOL(vcfg_common->load_system_certs, load_system_certs)) {
X509_STORE_set_default_paths(vcfg_common->tcs);
X509_STORE_set_default_paths(vcfg_common->tcs->store);
}
if (!ast_strlen_zero(vcfg_common->crl_file)
|| !ast_strlen_zero(vcfg_common->crl_path)) {
X509_STORE_set_flags(vcfg_common->tcs, X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL);
X509_STORE_set_flags(vcfg_common->tcs->store, X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL);
}
}

Loading…
Cancel
Save