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;
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)) {
return -1;
}
- if (!store) {
+ if (!store || !store->store) {
ast_log(LOG_ERROR, "store is NULL");
return -1;
}
* 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;
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);
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;
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;
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");
*/
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
* \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
* \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);
/*!
* \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
* \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
* \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
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;
}
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);
}
}