res_stir_shaken: Implemented signature verification.

There are a lot of moving parts in this patch, but the focus of it is on
the verification of the signature using a public key located at the
public key URL provided in the JSON payload. First, we check the
database to see if we have already downloaded the key. If so, check to
see if it has expired. If it has, redownload from the URL. If we don't
have an entry in the database, just go ahead and download the public
key. The expiration is tested each time we download the file. After
that, read the public key from the file and use it to verify the
signature. All sanity checking is done when the payload is first
received, so the verification is complete once this point is reached.

The XML has also been added since a new config option was added to
general (curl_timeout). The maximum amount of time to wait for a
download can be configured through this option, with a low value by
default.

Change-Id: I3ba4c63880493bf8c7d17a9cfca1af0e934d1a1c
This commit is contained in:
Ben Ford
2020-04-15 13:15:21 -05:00
committed by Joshua Colp
parent 7baf2c4bf1
commit 9acf840f7c
11 changed files with 832 additions and 18 deletions

View File

@@ -30,6 +30,7 @@
#define DEFAULT_CA_FILE ""
#define DEFAULT_CA_PATH ""
#define DEFAULT_CACHE_MAX_SIZE 1000
#define DEFAULT_CURL_TIMEOUT 2
struct stir_shaken_general {
SORCERY_OBJECT(details);
@@ -41,6 +42,8 @@ struct stir_shaken_general {
);
/*! Maximum size of public keys cache */
unsigned int cache_max_size;
/*! Maximum time to wait to CURL certificates */
unsigned int curl_timeout;
};
static struct stir_shaken_general *default_config = NULL;
@@ -78,6 +81,11 @@ unsigned int ast_stir_shaken_cache_max_size(const struct stir_shaken_general *cf
return cfg ? cfg->cache_max_size : DEFAULT_CACHE_MAX_SIZE;
}
unsigned int ast_stir_shaken_curl_timeout(const struct stir_shaken_general *cfg)
{
return cfg ? cfg->curl_timeout : DEFAULT_CURL_TIMEOUT;
}
static void stir_shaken_general_destructor(void *obj)
{
struct stir_shaken_general *cfg = obj;
@@ -250,6 +258,9 @@ int stir_shaken_general_load(void)
ast_sorcery_object_field_register(sorcery, CONFIG_TYPE, "cache_max_size",
__stringify(DEFAULT_CACHE_MAX_SIZE), OPT_UINT_T, 0,
FLDSET(struct stir_shaken_general, cache_max_size));
ast_sorcery_object_field_register(sorcery, CONFIG_TYPE, "curl_timeout",
__stringify(DEFAULT_CURL_TIMEOUT), OPT_UINT_T, 0,
FLDSET(struct stir_shaken_general, curl_timeout));
if (ast_sorcery_instance_observer_add(sorcery, &stir_shaken_general_observer)) {
ast_log(LOG_ERROR, "stir/shaken - failed to register loaded observer for '%s' "