Skip to content

Commit

Permalink
guest/read: split print_variables into two functions
Browse files Browse the repository at this point in the history
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 <[email protected]>
  • Loading branch information
erichte-ibm committed Oct 6, 2023
1 parent 245fc67 commit efdb02f
Show file tree
Hide file tree
Showing 4 changed files with 88 additions and 70 deletions.
135 changes: 76 additions & 59 deletions backends/guest/common/read.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
*
Expand All @@ -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;
Expand All @@ -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,
Expand Down
5 changes: 3 additions & 2 deletions backends/guest/common/verify.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include <fcntl.h>
#include <unistd.h>
#include <argp.h>
#include "common/read.h"
#include "err.h"
#include "prlog.h"
#include "generic.h"
Expand Down Expand Up @@ -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;
}
Expand Down
16 changes: 8 additions & 8 deletions backends/guest/guest_svc_read.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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);
Expand All @@ -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]);
Expand Down
2 changes: 1 addition & 1 deletion backends/guest/include/common/read.h
Original file line number Diff line number Diff line change
Expand Up @@ -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

0 comments on commit efdb02f

Please sign in to comment.