From efdb02f1be20e20d9027100aca54513520e9bc70 Mon Sep 17 00:00:00 2001 From: Eric Richter Date: Fri, 6 Oct 2023 13:13:14 -0500 Subject: [PATCH] guest/read: split print_variables into two functions To avoid excessive nested scopes and indentation, split the ESD printing logic out into its own function print_esd_from_esl_buffer, and rename the previous function to print_esl_buffer. For the moment, print_esd_from_esl_buffer is declared as static and only used by print_esl_buffer, though this can be exposed as a helper for use elsewhere in the code if need be (though may want to change the input type to sv_esl_t and calculate signature_type inside). Signed-off-by: Eric Richter --- backends/guest/common/read.c | 135 +++++++++++++++------------ backends/guest/common/verify.c | 5 +- backends/guest/guest_svc_read.c | 16 ++-- backends/guest/include/common/read.h | 2 +- 4 files changed, 88 insertions(+), 70 deletions(-) diff --git a/backends/guest/common/read.c b/backends/guest/common/read.c index ae372011..2904db38 100644 --- a/backends/guest/common/read.c +++ b/backends/guest/common/read.c @@ -111,6 +111,77 @@ int print_cert_info(crypto_x509_t *x509) return SUCCESS; } +/* + * prints ESDs inside an ESL buffer in human readable form + * + * @param esl, pointer to the beginning of valid esl data. NOTE: caller is responsible for validation + * @param esl_size, size of the esl data buffer + * @param sig_type, signature type enum as extracted from e.g. get_signature_type + * @return SUCCESS or propogates error code + */ +static int print_esd_from_esl_buffer(const uint8_t *esl, size_t esl_size, + enum signature_type sig_type) +{ + crypto_x509_t *x509 = NULL; + int rc; + size_t esd_data_size, esd_count = 0; + uuid_t esd_owner; + union { + const uint8_t *raw; + sv_esd_t *esd; + } curr_esd; + curr_esd.raw = NULL; + + rc = next_esd_from_esl(esl, &curr_esd.raw, &esd_data_size, &esd_owner); + if (rc) { + prlog(PR_ERR, "Error reading esd from esl, rc = %d\n", rc); + return rc; + } + + while (curr_esd.esd != NULL) { + esd_count++; + switch (sig_type) { + case ST_HASHES_START ... ST_HASHES_END: + printf("\tData-%zu: ", esd_count); + print_hex(curr_esd.raw, esd_data_size); + case ST_X509: + x509 = crypto_x509_parse_der(curr_esd.raw, esd_data_size); + if (!x509) + break; + printf("\tCertificate-%zu: ", esd_count); + rc = print_cert_info(x509); + + // we're done with the x509, free it immediately + crypto_x509_free(x509); + x509 = NULL; + + // ...then bail if there was an error printing the cert + if (rc) + return rc; + + break; + case ST_SBAT: + printf("\tData: "); + print_raw((char *)curr_esd.raw, esd_data_size); + break; + case ST_DELETE: + printf("\tDELETE-MSG: "); + print_raw((char *)curr_esd.raw, esd_data_size); + break; + default: + prlog(PR_ERR, "ERROR: invalid signature type = %d\n", sig_type); + break; + } + + rc = next_esd_from_esl(esl, &curr_esd.raw, &esd_data_size, &esd_owner); + if (rc) { + prlog(PR_ERR, "Error reading next esd (%zu), rc = %d\n", esd_count, rc); + } + } + + return SUCCESS; +} + /* * prints human readable data in of ESL buffer * @@ -119,12 +190,12 @@ int print_cert_info(crypto_x509_t *x509) * @param var_name, secure boot variable name * @return SUCCESS or error number if failure */ -int print_variables(const uint8_t *buffer, size_t buffer_size, const char *var_name) +int print_esl_buffer(const uint8_t *buffer, size_t buffer_size, const char *var_name) { int rc; size_t esl_data_size = 0; size_t esl_count = 0; - crypto_x509_t *x509 = NULL; + enum signature_type sig_type; union { const uint8_t *raw; @@ -139,69 +210,15 @@ int print_variables(const uint8_t *buffer, size_t buffer_size, const char *var_n } while (curr_esl.esl != NULL) { - size_t esd_count = 0; esl_count++; printf("ESL %zu:\n", esl_count); print_esl_info(curr_esl.esl); - union { - const uint8_t *raw; - sv_esd_t *esd; - } curr_esd; - curr_esd.raw = NULL; - - size_t esd_data_size; - uuid_t esd_owner; - enum signature_type sig_type = get_signature_type(curr_esl.esl->signature_type); - - rc = next_esd_from_esl(curr_esl.raw, &curr_esd.raw, &esd_data_size, &esd_owner); - if (rc) { - prlog(PR_ERR, "Error reading esd from esl %zu, rc = %d\n", esl_count, rc); + sig_type = get_signature_type(curr_esl.esl->signature_type); + rc = print_esd_from_esl_buffer(curr_esl.raw, esl_data_size, sig_type); + if (rc) return rc; - } - while (curr_esd.esd != NULL) { - esd_count++; - switch (sig_type) { - case ST_HASHES_START ... ST_HASHES_END: - printf("\tData-%zu: ", esd_count); - print_hex(curr_esd.raw, esd_data_size); - case ST_X509: - x509 = crypto_x509_parse_der(curr_esd.raw, esd_data_size); - if (!x509) - break; - printf("\tCertificate-%zu: ", esd_count); - rc = print_cert_info(x509); - - // we're done with the x509, free it immediately - crypto_x509_free(x509); - x509 = NULL; - - // ...then bail if there was an error printing the cert - if (rc) - return rc; - - break; - case ST_SBAT: - printf("\tData: "); - print_raw((char *)curr_esd.raw, esd_data_size); - break; - case ST_DELETE: - printf("\tDELETE-MSG: "); - print_raw((char *)curr_esd.raw, esd_data_size); - break; - default: - prlog(PR_ERR, "ERROR: invalid signature type = %d\n", sig_type); - break; - } - - rc = next_esd_from_esl(curr_esl.raw, &curr_esd.raw, &esd_data_size, - &esd_owner); - if (rc) { - prlog(PR_ERR, "Error reading next esd (%zu), rc = %d\n", esd_count, - rc); - } - } rc = next_esl_from_buffer(buffer, buffer_size, &curr_esl.raw, &esl_data_size); if (rc) { prlog(PR_ERR, "Error reading next esl (%zu) from buffer: %d\n", esl_count, diff --git a/backends/guest/common/verify.c b/backends/guest/common/verify.c index a5a28498..c98ef5e2 100644 --- a/backends/guest/common/verify.c +++ b/backends/guest/common/verify.c @@ -8,6 +8,7 @@ #include #include #include +#include "common/read.h" #include "err.h" #include "prlog.h" #include "generic.h" @@ -70,8 +71,8 @@ static int update_variable(const char *variable_name, const uint8_t *auth_data, prlog(PR_INFO, "\tappend update: %s\n\n", (append_update ? "True" : "False")); if (*new_esl_data != NULL) { - rc = print_variables((*new_esl_data + TIMESTAMP_LEN), - (*new_esl_data_size - TIMESTAMP_LEN), variable_name); + rc = print_esl_buffer((*new_esl_data + TIMESTAMP_LEN), + (*new_esl_data_size - TIMESTAMP_LEN), variable_name); if (rc != SUCCESS) return rc; } diff --git a/backends/guest/guest_svc_read.c b/backends/guest/guest_svc_read.c index 9a9e4f26..753f40ba 100644 --- a/backends/guest/guest_svc_read.c +++ b/backends/guest/guest_svc_read.c @@ -153,7 +153,7 @@ static int read_esl(const uint8_t *esl_data, const size_t esl_data_len, const in return rc; } - rc = print_variables(esl_data, esl_data_len, variable_name); + rc = print_esl_buffer(esl_data, esl_data_len, variable_name); return rc; } @@ -230,8 +230,8 @@ static int read_auth(const uint8_t *auth_data, size_t auth_data_len, const int i if (auth_size == auth_data_len) printf("ESL is empty, it is reset file.\n"); else - rc = print_variables(auth_data + APPEND_HEADER_LEN + auth_size, - auth_data_len - auth_size, variable_name); + rc = print_esl_buffer(auth_data + APPEND_HEADER_LEN + auth_size, + auth_data_len - auth_size, variable_name); return rc; } @@ -262,8 +262,8 @@ static int read_path(const char *path, const int is_print_raw, const char *varia if (is_print_raw || esl_data_size == DEFAULT_PK_LEN) print_raw((char *)esl_data, esl_data_size); else if (esl_data_size >= TIMESTAMP_LEN) - rc = print_variables(esl_data + TIMESTAMP_LEN, - esl_data_size - TIMESTAMP_LEN, variable_name); + rc = print_esl_buffer(esl_data + TIMESTAMP_LEN, + esl_data_size - TIMESTAMP_LEN, variable_name); else prlog(PR_WARNING, "WARNING: The %s database is empty.\n", variable_name); @@ -290,9 +290,9 @@ static int read_path(const char *path, const int is_print_raw, const char *varia strcmp(defined_sb_variables[i], PK_VARIABLE) == 0)) print_raw((char *)esl_data, esl_data_size); else if (esl_data_size >= TIMESTAMP_LEN) - rc = print_variables(esl_data + TIMESTAMP_LEN, - esl_data_size - TIMESTAMP_LEN, - defined_sb_variables[i]); + rc = print_esl_buffer(esl_data + TIMESTAMP_LEN, + esl_data_size - TIMESTAMP_LEN, + defined_sb_variables[i]); else prlog(PR_WARNING, "WARNING: The %s database is empty.\n", defined_sb_variables[i]); diff --git a/backends/guest/include/common/read.h b/backends/guest/include/common/read.h index a455d2df..4a5527f7 100644 --- a/backends/guest/include/common/read.h +++ b/backends/guest/include/common/read.h @@ -61,6 +61,6 @@ void print_timestamp(timestamp_t t); * @param key, variable name {"db","dbx","KEK", "PK"} b/c dbx is a different format * @return SUCCESS or error number if failure */ -int print_variables(const uint8_t *buffer, size_t buffer_size, const char *var_name); +int print_esl_buffer(const uint8_t *buffer, size_t buffer_size, const char *var_name); #endif