diff --git a/library/spdm_requester_lib/libspdm_req_get_csr.c b/library/spdm_requester_lib/libspdm_req_get_csr.c index 51a4423fe48..2414584cb09 100644 --- a/library/spdm_requester_lib/libspdm_req_get_csr.c +++ b/library/spdm_requester_lib/libspdm_req_get_csr.c @@ -58,7 +58,6 @@ 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; @@ -66,10 +65,15 @@ static libspdm_return_t libspdm_try_get_csr(libspdm_context_t *spdm_context, } 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; @@ -77,9 +81,6 @@ static libspdm_return_t libspdm_try_get_csr(libspdm_context_t *spdm_context, } } - /* 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 < diff --git a/library/spdm_requester_lib/libspdm_req_handle_error_response.c b/library/spdm_requester_lib/libspdm_req_handle_error_response.c index a1f48efe982..362f74a12d2 100644 --- a/library/spdm_requester_lib/libspdm_req_handle_error_response.c +++ b/library/spdm_requester_lib/libspdm_req_handle_error_response.c @@ -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; } } diff --git a/library/spdm_requester_lib/libspdm_req_set_certificate.c b/library/spdm_requester_lib/libspdm_req_set_certificate.c index fd137d301d8..3e2e7925678 100644 --- a/library/spdm_requester_lib/libspdm_req_set_certificate.c +++ b/library/spdm_requester_lib/libspdm_req_set_certificate.c @@ -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; } diff --git a/unit_test/test_spdm_requester/get_csr.c b/unit_test/test_spdm_requester/get_csr.c index 6a7c5eb6bcf..850c05a339c 100644 --- a/unit_test/test_spdm_requester/get_csr.c +++ b/unit_test/test_spdm_requester/get_csr.c @@ -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; } @@ -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, @@ -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, @@ -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(