Skip to content

Commit

Permalink
Reinstate capability checks for 1.3 endpoints
Browse files Browse the repository at this point in the history
Fix #2503.

Signed-off-by: Steven Bellock <[email protected]>
  • Loading branch information
steven-bellock committed Jan 19, 2024
1 parent f8de90b commit e1d0ef3
Show file tree
Hide file tree
Showing 4 changed files with 91 additions and 16 deletions.
11 changes: 6 additions & 5 deletions library/spdm_requester_lib/libspdm_req_get_csr.c
Original file line number Diff line number Diff line change
Expand Up @@ -58,28 +58,29 @@ static libspdm_return_t libspdm_try_get_csr(libspdm_context_t *spdm_context,
if (libspdm_get_connection_version(spdm_context) < SPDM_MESSAGE_VERSION_12) {
return LIBSPDM_STATUS_UNSUPPORTED_CAP;
}

if (libspdm_get_connection_version(spdm_context) == SPDM_MESSAGE_VERSION_12) {
if ((key_pair_id != 0) || (request_attribute != 0)) {
return LIBSPDM_STATUS_INVALID_PARAMETER;
}
}

if (libspdm_get_connection_version(spdm_context) >= SPDM_MESSAGE_VERSION_13) {
/* CSR_CAP for a 1.2 Responder is not checked because it was not defined in SPDM 1.2.0. */
if (!libspdm_is_capabilities_flag_supported(
spdm_context, true, 0,
SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CSR_CAP)) {
return LIBSPDM_STATUS_UNSUPPORTED_CAP;
}
if ((spdm_context->connection_info.multi_key_conn_rsp) == (key_pair_id == 0)) {
return LIBSPDM_STATUS_INVALID_PARAMETER;
}

if (!spdm_context->connection_info.multi_key_conn_rsp) {
if ((request_attribute & SPDM_GET_CSR_REQUEST_ATTRIBUTES_CERT_MODEL_MASK) != 0) {
return LIBSPDM_STATUS_INVALID_PARAMETER;
}
}
}

/* Do not check the Responder's CSR_CAP capability as it may be a 1.2.0 Responder
* and that capability does not exist. */

LIBSPDM_ASSERT(opaque_data_length < SPDM_MAX_OPAQUE_DATA_SIZE);

if (spdm_context->connection_info.connection_state <
Expand Down
11 changes: 8 additions & 3 deletions library/spdm_requester_lib/libspdm_req_handle_error_response.c
Original file line number Diff line number Diff line change
Expand Up @@ -118,10 +118,15 @@ libspdm_return_t libspdm_handle_simple_error_response(libspdm_context_t *spdm_co
if ((last_spdm_request->header.request_response_code == SPDM_SET_CERTIFICATE) ||
(last_spdm_request->header.request_response_code == SPDM_GET_CSR)) {

/* Do not check the Responder's CERT_INSTALL_RESET_CAP capability as it may be a 1.2.0
* Responder and that capability does not exist. */

if (error_code == SPDM_ERROR_CODE_RESET_REQUIRED) {
if ((libspdm_get_connection_version(spdm_context) >= SPDM_MESSAGE_VERSION_13) &&
!libspdm_is_capabilities_flag_supported(
spdm_context, true, 0,
SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_INSTALL_RESET_CAP)) {
return LIBSPDM_STATUS_ERROR_PEER;
}
/* CERT_INSTALL_RESET_CAP for a 1.2 Responder is not checked because it was not defined
* in SPDM 1.2.0. */
return LIBSPDM_STATUS_RESET_REQUIRED_PEER;
}
}
Expand Down
19 changes: 11 additions & 8 deletions library/spdm_requester_lib/libspdm_req_set_certificate.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,23 +45,26 @@ static libspdm_return_t libspdm_try_set_certificate(libspdm_context_t *spdm_cont
libspdm_session_info_t *session_info;
libspdm_session_state_t session_state;

LIBSPDM_ASSERT(slot_id < SPDM_MAX_SLOT_COUNT);

if (libspdm_get_connection_version(spdm_context) < SPDM_MESSAGE_VERSION_12) {
return LIBSPDM_STATUS_UNSUPPORTED_CAP;
}

/* Do not check the Responder's SET_CERT_CAP capability as it may be a 1.2.0 Responder
* and that capability does not exist. */

LIBSPDM_ASSERT(slot_id < SPDM_MAX_SLOT_COUNT);

if (libspdm_get_connection_version (spdm_context) < SPDM_MESSAGE_VERSION_13) {
if ((cert_chain == NULL) || (cert_chain_size == 0)) {
return LIBSPDM_STATUS_INVALID_PARAMETER;
}
}
/* SET_CERT_CAP for a 1.2 Responder is not checked because it was not defined in SPDM 1.2.0. */
if (libspdm_get_connection_version (spdm_context) >= SPDM_MESSAGE_VERSION_13) {
if (!libspdm_is_capabilities_flag_supported(
spdm_context, true, 0,
SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_SET_CERT_CAP)) {
return LIBSPDM_STATUS_UNSUPPORTED_CAP;
}
}

if (spdm_context->connection_info.connection_state <
LIBSPDM_CONNECTION_STATE_NEGOTIATED) {
if (spdm_context->connection_info.connection_state < LIBSPDM_CONNECTION_STATE_NEGOTIATED) {
return LIBSPDM_STATUS_INVALID_STATE_LOCAL;
}

Expand Down
66 changes: 66 additions & 0 deletions unit_test/test_spdm_requester/get_csr.c
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,8 @@ libspdm_return_t libspdm_requester_get_csr_test_send_message(
}
case 0x5:
return LIBSPDM_STATUS_SUCCESS;
case 0x6:
return LIBSPDM_STATUS_SUCCESS;
default:
return LIBSPDM_STATUS_SEND_FAIL;
}
Expand Down Expand Up @@ -260,6 +262,26 @@ libspdm_return_t libspdm_requester_get_csr_test_receive_message(
spdm_response->csr_length = (uint16_t)global_csr_len;
spdm_response->reserved = 0;

libspdm_transport_test_encode_message(spdm_context, NULL, false,
false, spdm_response_size,
spdm_response, response_size,
response);
}
return LIBSPDM_STATUS_SUCCESS;
case 0x6: {
spdm_error_response_t *spdm_response;
size_t spdm_response_size;
size_t transport_header_size;

spdm_response_size = sizeof(spdm_error_response_t);
transport_header_size = LIBSPDM_TEST_TRANSPORT_HEADER_SIZE;
spdm_response = (void *)((uint8_t *)*response + transport_header_size);

spdm_response->header.spdm_version = SPDM_MESSAGE_VERSION_13;
spdm_response->header.request_response_code = SPDM_ERROR;
spdm_response->header.param1 = SPDM_ERROR_CODE_RESET_REQUIRED;
spdm_response->header.param2 = 1;

libspdm_transport_test_encode_message(spdm_context, NULL, false,
false, spdm_response_size,
spdm_response, response_size,
Expand Down Expand Up @@ -465,6 +487,48 @@ void libspdm_test_requester_get_csr_case5(void **state)
#endif /*LIBSPDM_ENABLE_CAPABILITY_CSR_CAP_EX*/
}

/**
* Test 6: A 1.3 Responder returns ResetRequired when its CERT_INSTALL_RESET_CAP is 0.
* Expected Behavior: libspdm returns LIBSPDM_STATUS_ERROR_PEER since Responder should
* not produce that error message unless CERT_INSTALL_RESET_CAP is 1.
**/
void libspdm_test_requester_get_csr_case6(void **state)
{
libspdm_return_t status;
libspdm_test_context_t *spdm_test_context;
libspdm_context_t *spdm_context;

uint8_t csr_form_get[LIBSPDM_MAX_CSR_SIZE] = {0};
size_t csr_len;

csr_len = LIBSPDM_MAX_CSR_SIZE;

spdm_test_context = *state;
spdm_context = spdm_test_context->spdm_context;
spdm_test_context->case_id = 0x6;
spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_13 <<
SPDM_VERSION_NUMBER_SHIFT_BIT;

spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_NEGOTIATED;
spdm_context->local_context.capability.flags = 0;
/* Don't set CERT_INSTALL_RESET_CAP. */
spdm_context->connection_info.capability.flags = SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CSR_CAP;

spdm_context->connection_info.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
spdm_context->connection_info.algorithm.base_asym_algo = m_libspdm_use_asym_algo;

spdm_context->connection_info.algorithm.other_params_support =
SPDM_ALGORITHMS_OPAQUE_DATA_FORMAT_0;

status = libspdm_get_csr(spdm_context, NULL,
right_req_info, right_req_info_size,
m_csr_opaque_data, m_csr_opaque_data_size,
(void *)&csr_form_get, &csr_len);

assert_int_equal(status, LIBSPDM_STATUS_ERROR_PEER);
}


libspdm_test_context_t m_libspdm_requester_get_csr_test_context = {
LIBSPDM_TEST_CONTEXT_VERSION,
true,
Expand All @@ -485,6 +549,8 @@ int libspdm_requester_get_csr_test_main(void)
cmocka_unit_test(libspdm_test_requester_get_csr_case4),
/* Successful response to libspdm_get_csr_ex with a reset required */
cmocka_unit_test(libspdm_test_requester_get_csr_case5),
/* Illegal ResetRequired error response. */
cmocka_unit_test(libspdm_test_requester_get_csr_case6),
};

libspdm_setup_test_context(
Expand Down

0 comments on commit e1d0ef3

Please sign in to comment.