res_stir_shaken.so: Handle X5U certificate chains.

The verification process will now load a full certificate chain retrieved
via the X5U URL instead of loading only the end user cert.

* Renamed crypto_load_cert_from_file() and crypto_load_cert_from_memory()
to crypto_load_cert_chain_from_file() and crypto_load_cert_chain_from_memory()
respectively.

* The two load functions now continue to load certs from the file or memory
PEMs and store them in a separate stack of untrusted certs specific to the
current verification context.

* crypto_is_cert_trusted() now uses the stack of untrusted certs that were
extracted from the PEM in addition to any untrusted certs that were passed
in from the configuration (and any CA certs passed in from the config of
course).

Resolves: #1272

UserNote: The STIR/SHAKEN verification process will now load a full
certificate chain retrieved via the X5U URL instead of loading only
the end user cert.
This commit is contained in:
George Joseph
2025-06-18 14:38:08 -06:00
committed by github-actions[bot]
parent fe341c2b0f
commit 8b8a8c1475
6 changed files with 180 additions and 29 deletions

View File

@@ -345,7 +345,8 @@ static enum ast_stir_shaken_vs_response_code check_cert(
}
ast_trace(3,"%s: Checking ctx against CA ctx\n", ctx->tag);
res = crypto_is_cert_trusted(ctx->eprofile->vcfg_common.tcs, ctx->xcert, &err_msg);
res = crypto_is_cert_trusted(ctx->eprofile->vcfg_common.tcs, ctx->xcert,
ctx->cert_chain, &err_msg);
if (!res) {
SCOPE_EXIT_LOG_RTN_VALUE(AST_STIR_SHAKEN_VS_CERT_NOT_TRUSTED,
LOG_ERROR, "%s: Cert '%s' not trusted: %s\n",
@@ -429,8 +430,8 @@ static enum ast_stir_shaken_vs_response_code retrieve_cert_from_url(
ctx->tag, ctx->public_url);
}
ctx->xcert = crypto_load_cert_from_memory(write_data->stream_buffer,
write_data->stream_bytes_downloaded);
ctx->xcert = crypto_load_cert_chain_from_memory(write_data->stream_buffer,
write_data->stream_bytes_downloaded, &ctx->cert_chain);
if (!ctx->xcert) {
SCOPE_EXIT_LOG_RTN_VALUE(AST_STIR_SHAKEN_VS_CERT_CONTENTS_INVALID,
LOG_ERROR, "%s: Cert '%s' was not parseable as an X509 certificate\n",
@@ -524,7 +525,7 @@ static enum ast_stir_shaken_vs_response_code
ctx->tag, ctx->filename, ctx->public_url);
}
ctx->xcert = crypto_load_cert_from_file(ctx->filename);
ctx->xcert = crypto_load_cert_chain_from_file(ctx->filename, &ctx->cert_chain);
if (!ctx->xcert) {
cleanup_cert_from_astdb_and_fs(ctx);
SCOPE_EXIT_RTN_VALUE(AST_STIR_SHAKEN_VS_CERT_CONTENTS_INVALID,
@@ -651,6 +652,7 @@ static void ctx_destructor(void *obj)
ast_free(ctx->raw_key);
ast_string_field_free_memory(ctx);
X509_free(ctx->xcert);
sk_X509_free(ctx->cert_chain);
}
enum ast_stir_shaken_vs_response_code