mirror of
				https://github.com/asterisk/asterisk.git
				synced 2025-10-31 10:47:18 +00:00 
			
		
		
		
	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
(cherry picked from commit 4cb56ccd28)
			
			
This commit is contained in:
		
				
					committed by
					
						 Asterisk Development Team
						Asterisk Development Team
					
				
			
			
				
	
			
			
			
						parent
						
							ca6590426a
						
					
				
				
					commit
					2fd379d3be
				
			| @@ -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; | ||||
| 	struct crypto_cert_store *store = obj; | ||||
|  | ||||
| 	if (store->store) { | ||||
| 		X509_STORE_free(store->store); | ||||
| 	} | ||||
| 	X509_STORE_free(store); | ||||
| } | ||||
|  | ||||
| int crypto_lock_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; | ||||
| 	} | ||||
| 	/* lock returns 1 on success */ | ||||
| 	return X509_STORE_lock(store) == 1 ? 0 : -1; | ||||
| } | ||||
| 	store->store = X509_STORE_new(); | ||||
|  | ||||
| int crypto_unlock_cert_store(X509_STORE *store) | ||||
| { | ||||
| 	if (!store) { | ||||
| 		return -1; | ||||
| 	} | ||||
| 	/* 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(); | ||||
|  | ||||
| 	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); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user