LCOV - code coverage report
Current view: top level - unit_test/test_spdm_responder - encap_get_certificate.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 96.4 % 277 267
Test Date: 2026-02-22 08:11:49 Functions: 100.0 % 6 6

            Line data    Source code
       1              : /**
       2              :  *  Copyright Notice:
       3              :  *  Copyright 2021-2026 DMTF. All rights reserved.
       4              :  *  License: BSD 3-Clause License. For full text see link: https://github.com/DMTF/libspdm/blob/main/LICENSE.md
       5              :  **/
       6              : #include "spdm_unit_test.h"
       7              : #include "internal/libspdm_responder_lib.h"
       8              : 
       9              : #if (LIBSPDM_ENABLE_CAPABILITY_MUT_AUTH_CAP) && (LIBSPDM_ENABLE_CAPABILITY_ENCAP_CAP) && \
      10              :     (LIBSPDM_SEND_GET_CERTIFICATE_SUPPORT)
      11              : 
      12              : static void *m_libspdm_local_certificate_chain;
      13              : static size_t m_libspdm_local_certificate_chain_size;
      14              : 
      15              : spdm_certificate_response_t m_spdm_get_certificate_response1;
      16              : size_t m_spdm_get_certificate_response1_size;
      17              : 
      18              : spdm_certificate_response_t m_spdm_get_certificate_response2 = {
      19              :     {SPDM_MESSAGE_VERSION_10, SPDM_ERROR, SPDM_ERROR_CODE_INVALID_REQUEST, 0},
      20              :     0,
      21              :     0
      22              : };
      23              : size_t m_spdm_get_certificate_response2_size = sizeof(m_spdm_get_certificate_response2);
      24              : 
      25              : /**
      26              :  * Test 1: Normal case, request a certificate chain
      27              :  * Expected Behavior: receives a valid certificate chain with the correct number of Certificate messages
      28              :  **/
      29            1 : static void rsp_encap_get_certificate_case1(void **state)
      30              : {
      31              :     libspdm_return_t status;
      32              :     libspdm_test_context_t *spdm_test_context;
      33              :     libspdm_context_t *spdm_context;
      34              :     void *data;
      35              :     size_t data_size;
      36              :     void *hash;
      37              :     size_t hash_size;
      38              :     const uint8_t *root_cert;
      39              :     size_t root_cert_size;
      40              :     bool need_continue;
      41              :     spdm_certificate_response_t *spdm_response;
      42              :     uint8_t temp_buf[LIBSPDM_MAX_SPDM_MSG_SIZE];
      43              :     size_t temp_buf_size;
      44              :     uint16_t portion_length;
      45              :     uint16_t remainder_length;
      46              :     static size_t calling_index = 0;
      47              :     size_t spdm_response_size;
      48              : 
      49            1 :     spdm_test_context = *state;
      50            1 :     spdm_context = spdm_test_context->spdm_context;
      51            1 :     spdm_test_context->case_id = 0x1;
      52            1 :     spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_10 <<
      53              :                                             SPDM_VERSION_NUMBER_SHIFT_BIT;
      54            1 :     spdm_context->connection_info.capability.flags |= SPDM_GET_CAPABILITIES_REQUEST_FLAGS_CERT_CAP;
      55            1 :     if (!libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
      56              :                                                          m_libspdm_use_asym_algo, &data,
      57              :                                                          &data_size, &hash, &hash_size)) {
      58            0 :         assert(false);
      59              :     }
      60            1 :     if (!libspdm_x509_get_cert_from_cert_chain(
      61            1 :             (uint8_t *)data + sizeof(spdm_cert_chain_t) + hash_size,
      62            1 :             data_size - sizeof(spdm_cert_chain_t) - hash_size, 0, &root_cert, &root_cert_size)) {
      63            0 :         assert(false);
      64              :     }
      65            1 :     libspdm_dump_hex( root_cert, root_cert_size);
      66            1 :     spdm_context->local_context.peer_root_cert_provision_size[0] = root_cert_size;
      67            1 :     spdm_context->local_context.peer_root_cert_provision[0] = root_cert;
      68            1 :     libspdm_reset_message_b(spdm_context);
      69            1 :     spdm_context->connection_info.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
      70              : 
      71            1 :     spdm_context->connection_info.algorithm.req_base_asym_alg =
      72              :         SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P256;
      73              : 
      74            1 :     if (m_libspdm_local_certificate_chain == NULL) {
      75            1 :         libspdm_read_responder_public_certificate_chain(
      76              :             m_libspdm_use_hash_algo, m_libspdm_use_asym_algo,
      77              :             &m_libspdm_local_certificate_chain,
      78              :             &m_libspdm_local_certificate_chain_size, NULL, NULL);
      79              :     }
      80              : 
      81            1 :     portion_length = LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN;
      82            1 :     remainder_length =
      83            1 :         (uint16_t)(m_libspdm_local_certificate_chain_size -
      84              :                    LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN *
      85            1 :                    (calling_index + 1));
      86              : 
      87            1 :     temp_buf_size = sizeof(spdm_certificate_response_t) + portion_length;
      88            1 :     spdm_response_size = temp_buf_size;
      89            1 :     spdm_response = (void *)temp_buf;
      90              : 
      91            1 :     spdm_response->header.spdm_version = SPDM_MESSAGE_VERSION_10;
      92            1 :     spdm_response->header.request_response_code = SPDM_CERTIFICATE;
      93            1 :     spdm_response->header.param1 = 0;
      94            1 :     spdm_response->header.param2 = 0;
      95            1 :     spdm_response->portion_length = portion_length;
      96            1 :     spdm_response->remainder_length = remainder_length;
      97            1 :     libspdm_copy_mem(spdm_response + 1,
      98              :                      sizeof(temp_buf) - sizeof(*spdm_response),
      99            1 :                      (uint8_t *)m_libspdm_local_certificate_chain +
     100            1 :                      LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN * calling_index,
     101              :                      portion_length);
     102              : 
     103            1 :     free(m_libspdm_local_certificate_chain);
     104            1 :     m_libspdm_local_certificate_chain = NULL;
     105            1 :     m_libspdm_local_certificate_chain_size = 0;
     106              : 
     107            1 :     status = libspdm_process_encap_response_certificate(spdm_context, spdm_response_size,
     108              :                                                         spdm_response,
     109              :                                                         &need_continue);
     110            1 :     assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
     111              : 
     112            1 :     spdm_context->mut_auth_cert_chain_buffer_size = 0;
     113            1 :     free(data);
     114            1 : }
     115              : 
     116              : 
     117              : /**
     118              :  * Test 2: force responder to send an ERROR message with code SPDM_ERROR_CODE_INVALID_REQUEST
     119              :  * Expected Behavior: get a RETURN_DEVICE_ERROR, with no CERTIFICATE messages received (checked in transcript.message_b buffer)
     120              :  **/
     121            2 : static void rsp_encap_get_certificate_case2(void **state)
     122              : {
     123              :     libspdm_return_t status;
     124              :     libspdm_test_context_t *spdm_test_context;
     125              :     libspdm_context_t *spdm_context;
     126              : 
     127              :     void *data;
     128              :     size_t data_size;
     129              :     void *hash;
     130              :     size_t hash_size;
     131              :     const uint8_t *root_cert;
     132              :     size_t root_cert_size;
     133              :     bool need_continue;
     134              : 
     135            2 :     spdm_test_context = *state;
     136            2 :     spdm_context = spdm_test_context->spdm_context;
     137            2 :     spdm_test_context->case_id = 0x2;
     138            2 :     spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_10 <<
     139              :                                             SPDM_VERSION_NUMBER_SHIFT_BIT;
     140            2 :     spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_AFTER_DIGESTS;
     141            2 :     spdm_context->connection_info.capability.flags |= SPDM_GET_CAPABILITIES_REQUEST_FLAGS_CERT_CAP;
     142            2 :     if (!libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
     143              :                                                          m_libspdm_use_asym_algo, &data,
     144              :                                                          &data_size, &hash, &hash_size)) {
     145            0 :         assert(false);
     146              :     }
     147            2 :     if (!libspdm_x509_get_cert_from_cert_chain(
     148            2 :             (uint8_t *)data + sizeof(spdm_cert_chain_t) + hash_size,
     149            2 :             data_size - sizeof(spdm_cert_chain_t) - hash_size, 0, &root_cert, &root_cert_size)) {
     150            0 :         assert(false);
     151              :     }
     152            2 :     spdm_context->local_context.peer_root_cert_provision_size[0] = root_cert_size;
     153            2 :     spdm_context->local_context.peer_root_cert_provision[0] = root_cert;
     154            2 :     libspdm_reset_message_b(spdm_context);
     155            2 :     spdm_context->connection_info.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
     156              : 
     157            2 :     spdm_context->connection_info.algorithm.req_base_asym_alg =
     158              :         SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P256;
     159              : 
     160            2 :     status = libspdm_process_encap_response_certificate(spdm_context,
     161              :                                                         m_spdm_get_certificate_response2_size,
     162              :                                                         &m_spdm_get_certificate_response2,
     163              :                                                         &need_continue);
     164            2 :     assert_int_equal(status, LIBSPDM_STATUS_UNSUPPORTED_CAP);
     165              : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
     166              :     assert_int_equal(spdm_context->transcript.message_b.buffer_size, 0);
     167              : #endif
     168              : 
     169            2 :     spdm_context->mut_auth_cert_chain_buffer_size = 0;
     170            2 :     free(data);
     171            2 : }
     172              : 
     173              : /**
     174              :  * Test 3: Fail case, request a certificate chain,
     175              :  * spdm_request.offset + spdm_response.portion_length + spdm_response.remainder_length !=
     176              :  * total_responder_cert_chain_buffer_length.
     177              :  * Expected Behavior:returns a status of RETURN_DEVICE_ERROR.
     178              :  **/
     179            1 : static void rsp_encap_get_certificate_case3(void **state)
     180              : {
     181              :     libspdm_return_t status;
     182              :     libspdm_test_context_t *spdm_test_context;
     183              :     libspdm_context_t *spdm_context;
     184              :     void *data;
     185              :     size_t data_size;
     186              :     void *hash;
     187              :     size_t hash_size;
     188              :     const uint8_t *root_cert;
     189              :     size_t root_cert_size;
     190              :     bool need_continue;
     191              :     spdm_certificate_response_t *spdm_response;
     192              :     uint8_t temp_buf[LIBSPDM_MAX_SPDM_MSG_SIZE];
     193              :     size_t temp_buf_size;
     194              :     uint16_t portion_length;
     195              :     uint16_t remainder_length;
     196              :     static size_t calling_index = 0;
     197              :     size_t spdm_response_size;
     198              : 
     199            1 :     spdm_test_context = *state;
     200            1 :     spdm_context = spdm_test_context->spdm_context;
     201            1 :     spdm_test_context->case_id = 0x3;
     202            1 :     spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_10 <<
     203              :                                             SPDM_VERSION_NUMBER_SHIFT_BIT;
     204            1 :     spdm_context->connection_info.capability.flags |= SPDM_GET_CAPABILITIES_REQUEST_FLAGS_CERT_CAP;
     205            1 :     if (!libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
     206              :                                                          m_libspdm_use_asym_algo, &data,
     207              :                                                          &data_size, &hash, &hash_size)) {
     208            0 :         assert(false);
     209              :     }
     210            1 :     if (!libspdm_x509_get_cert_from_cert_chain(
     211            1 :             (uint8_t *)data + sizeof(spdm_cert_chain_t) + hash_size,
     212            1 :             data_size - sizeof(spdm_cert_chain_t) - hash_size, 0, &root_cert, &root_cert_size)) {
     213            0 :         assert(false);
     214              :     }
     215            1 :     libspdm_dump_hex( root_cert, root_cert_size);
     216            1 :     spdm_context->local_context.peer_root_cert_provision_size[0] = root_cert_size;
     217            1 :     spdm_context->local_context.peer_root_cert_provision[0] = root_cert;
     218            1 :     libspdm_reset_message_b(spdm_context);
     219            1 :     spdm_context->connection_info.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
     220              : 
     221              : 
     222            1 :     spdm_context->connection_info.algorithm.req_base_asym_alg =
     223              :         SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P256;
     224              : 
     225            1 :     if (m_libspdm_local_certificate_chain == NULL) {
     226            1 :         libspdm_read_responder_public_certificate_chain(
     227              :             m_libspdm_use_hash_algo, m_libspdm_use_asym_algo,
     228              :             &m_libspdm_local_certificate_chain,
     229              :             &m_libspdm_local_certificate_chain_size, NULL, NULL);
     230              :     }
     231              : 
     232            1 :     portion_length = 0;
     233              :     /* Fail response: spdm_request.offset + spdm_response.portion_length + spdm_response.remainder_length !=
     234              :      * total_responder_cert_chain_buffer_length.*/
     235            1 :     remainder_length =
     236            1 :         (uint16_t)(m_libspdm_local_certificate_chain_size - 1 -
     237            1 :                    LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN * (calling_index + 1));
     238              : 
     239            1 :     temp_buf_size = sizeof(spdm_certificate_response_t) + portion_length;
     240            1 :     spdm_response_size = temp_buf_size;
     241            1 :     spdm_response = (void *)temp_buf;
     242              : 
     243            1 :     spdm_response->header.spdm_version = SPDM_MESSAGE_VERSION_10;
     244            1 :     spdm_response->header.request_response_code = SPDM_CERTIFICATE;
     245            1 :     spdm_response->header.param1 = 0;
     246            1 :     spdm_response->header.param2 = 0;
     247            1 :     spdm_response->portion_length = portion_length;
     248            1 :     spdm_response->remainder_length = remainder_length;
     249            1 :     libspdm_copy_mem(spdm_response + 1,
     250              :                      sizeof(temp_buf) - sizeof(*spdm_response),
     251            1 :                      (uint8_t *)m_libspdm_local_certificate_chain +
     252            1 :                      LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN * calling_index,
     253              :                      portion_length);
     254              : 
     255            1 :     free(m_libspdm_local_certificate_chain);
     256            1 :     m_libspdm_local_certificate_chain = NULL;
     257            1 :     m_libspdm_local_certificate_chain_size = 0;
     258              : 
     259            1 :     status = libspdm_process_encap_response_certificate(spdm_context, spdm_response_size,
     260              :                                                         spdm_response,
     261              :                                                         &need_continue);
     262            1 :     assert_int_equal(status, LIBSPDM_STATUS_INVALID_MSG_FIELD);
     263              : 
     264            1 :     spdm_context->mut_auth_cert_chain_buffer_size = 0;
     265            1 :     free(data);
     266            1 : }
     267              : 
     268              : /**
     269              :  * Test 4: Fail case, request a certificate chain, responder return portion_length > spdm_request.length.
     270              :  * Expected Behavior:returns a status of RETURN_DEVICE_ERROR.
     271              :  **/
     272            1 : static void rsp_encap_get_certificate_case4(void **state)
     273              : {
     274              :     libspdm_return_t status;
     275              :     libspdm_test_context_t *spdm_test_context;
     276              :     libspdm_context_t *spdm_context;
     277              :     void *data;
     278              :     size_t data_size;
     279              :     void *hash;
     280              :     size_t hash_size;
     281              :     const uint8_t *root_cert;
     282              :     size_t root_cert_size;
     283              :     bool need_continue;
     284              :     spdm_certificate_response_t *spdm_response;
     285              :     uint8_t temp_buf[LIBSPDM_MAX_SPDM_MSG_SIZE];
     286              :     size_t temp_buf_size;
     287              :     uint16_t portion_length;
     288              :     uint16_t remainder_length;
     289              :     static size_t calling_index = 0;
     290              :     size_t spdm_response_size;
     291              :     uint32_t original_max_spdm_msg_size;
     292              : 
     293            1 :     spdm_test_context = *state;
     294            1 :     spdm_context = spdm_test_context->spdm_context;
     295            1 :     spdm_test_context->case_id = 0x4;
     296            1 :     spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_10 <<
     297              :                                             SPDM_VERSION_NUMBER_SHIFT_BIT;
     298            1 :     spdm_context->connection_info.capability.flags |= SPDM_GET_CAPABILITIES_REQUEST_FLAGS_CERT_CAP;
     299              : 
     300              :     /* Set max_spdm_msg_size to small value to force responder to send portion_length
     301              :      * greater than request length */
     302            1 :     original_max_spdm_msg_size = spdm_context->local_context.capability.max_spdm_msg_size;
     303            1 :     spdm_context->local_context.capability.max_spdm_msg_size =
     304              :         LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN + sizeof(spdm_certificate_response_t);
     305            1 :     if (!libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
     306              :                                                          m_libspdm_use_asym_algo, &data,
     307              :                                                          &data_size, &hash, &hash_size)) {
     308            0 :         assert(false);
     309              :     }
     310            1 :     if (!libspdm_x509_get_cert_from_cert_chain(
     311            1 :             (uint8_t *)data + sizeof(spdm_cert_chain_t) + hash_size,
     312            1 :             data_size - sizeof(spdm_cert_chain_t) - hash_size, 0, &root_cert, &root_cert_size)) {
     313            0 :         assert(false);
     314              :     }
     315            1 :     libspdm_dump_hex( root_cert, root_cert_size);
     316            1 :     spdm_context->local_context.peer_root_cert_provision_size[0] = root_cert_size;
     317            1 :     spdm_context->local_context.peer_root_cert_provision[0] = root_cert;
     318            1 :     libspdm_reset_message_b(spdm_context);
     319            1 :     spdm_context->connection_info.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
     320              : 
     321            1 :     spdm_context->connection_info.algorithm.req_base_asym_alg =
     322              :         SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P256;
     323              : 
     324            1 :     if (m_libspdm_local_certificate_chain == NULL) {
     325            1 :         libspdm_read_responder_public_certificate_chain(
     326              :             m_libspdm_use_hash_algo, m_libspdm_use_asym_algo,
     327              :             &m_libspdm_local_certificate_chain,
     328              :             &m_libspdm_local_certificate_chain_size, NULL, NULL);
     329              :     }
     330              : 
     331            1 :     portion_length = LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN + 1; /* Fail response: responder return portion_length > spdm_request.length*/
     332            1 :     remainder_length =
     333            1 :         (uint16_t)(m_libspdm_local_certificate_chain_size - 1 -
     334            1 :                    LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN * (calling_index + 1));
     335              : 
     336            1 :     temp_buf_size = sizeof(spdm_certificate_response_t) + portion_length;
     337            1 :     spdm_response_size = temp_buf_size;
     338            1 :     spdm_response = (void *)temp_buf;
     339              : 
     340            1 :     spdm_response->header.spdm_version = SPDM_MESSAGE_VERSION_10;
     341            1 :     spdm_response->header.request_response_code = SPDM_CERTIFICATE;
     342            1 :     spdm_response->header.param1 = 0;
     343            1 :     spdm_response->header.param2 = 0;
     344            1 :     spdm_response->portion_length = portion_length;
     345            1 :     spdm_response->remainder_length = remainder_length;
     346            1 :     libspdm_copy_mem(spdm_response + 1,
     347              :                      sizeof(temp_buf) - sizeof(*spdm_response),
     348            1 :                      (uint8_t *)m_libspdm_local_certificate_chain +
     349            1 :                      LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN * calling_index,
     350              :                      portion_length);
     351              : 
     352            1 :     free(m_libspdm_local_certificate_chain);
     353            1 :     m_libspdm_local_certificate_chain = NULL;
     354            1 :     m_libspdm_local_certificate_chain_size = 0;
     355              : 
     356            1 :     status = libspdm_process_encap_response_certificate(spdm_context, spdm_response_size,
     357              :                                                         spdm_response,
     358              :                                                         &need_continue);
     359            1 :     assert_int_equal(status, LIBSPDM_STATUS_INVALID_MSG_FIELD);
     360              : 
     361            1 :     spdm_context->mut_auth_cert_chain_buffer_size = 0;
     362            1 :     spdm_context->local_context.capability.max_spdm_msg_size = original_max_spdm_msg_size;
     363            1 :     free(data);
     364            1 : }
     365              : 
     366              : /**
     367              :  * Test 5: check request attributes and response attributes ,
     368              :  * Set CertModel to determine whether it meets expectations
     369              :  * Expected Behavior: requester returns the status LIBSPDM_STATUS_SUCCESS
     370              :  * Expected Behavior: CertModel is GenericCert model and slot 0 , returns a status of RETURN_DEVICE_ERROR.
     371              :  * Expected Behavior: CertModel Value of 0 and certificate chain is valid, returns a status of RETURN_DEVICE_ERROR.
     372              :  **/
     373            1 : static void rsp_encap_get_certificate_case5(void **state)
     374              : {
     375              :     libspdm_return_t status;
     376              :     libspdm_test_context_t *spdm_test_context;
     377              :     libspdm_context_t *spdm_context;
     378              :     void *data;
     379              :     size_t data_size;
     380              :     void *hash;
     381              :     size_t hash_size;
     382              :     const uint8_t *root_cert;
     383              :     size_t root_cert_size;
     384              :     bool need_continue;
     385              :     spdm_certificate_response_t *spdm_response;
     386              :     uint8_t temp_buf[LIBSPDM_MAX_SPDM_MSG_SIZE];
     387              :     size_t temp_buf_size;
     388              :     uint8_t cert_chain[LIBSPDM_MAX_CERT_CHAIN_SIZE];
     389              :     uint16_t portion_length;
     390              :     uint16_t remainder_length;
     391              :     size_t spdm_response_size;
     392              : 
     393            1 :     spdm_test_context = *state;
     394            1 :     spdm_context = spdm_test_context->spdm_context;
     395            1 :     spdm_test_context->case_id = 0x5;
     396            1 :     spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_13 <<
     397              :                                             SPDM_VERSION_NUMBER_SHIFT_BIT;
     398            1 :     spdm_context->connection_info.capability.flags = 0;
     399            1 :     spdm_context->connection_info.capability.flags |= SPDM_GET_CAPABILITIES_REQUEST_FLAGS_CERT_CAP;
     400            1 :     spdm_context->connection_info.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
     401            1 :     spdm_context->connection_info.algorithm.req_base_asym_alg = m_libspdm_use_req_asym_algo;
     402              : 
     403            1 :     if (!libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
     404              :                                                          m_libspdm_use_asym_algo, &data,
     405              :                                                          &data_size, &hash, &hash_size)) {
     406            0 :         assert(false);
     407              :     }
     408            1 :     if (!libspdm_x509_get_cert_from_cert_chain(
     409            1 :             (uint8_t *)data + sizeof(spdm_cert_chain_t) + hash_size,
     410            1 :             data_size - sizeof(spdm_cert_chain_t) - hash_size, 0, &root_cert, &root_cert_size)) {
     411            0 :         assert(false);
     412              :     }
     413              : 
     414            1 :     spdm_context->local_context.peer_root_cert_provision_size[0] = root_cert_size;
     415            1 :     spdm_context->local_context.peer_root_cert_provision[0] = root_cert;
     416              : 
     417            1 :     libspdm_read_responder_public_certificate_chain(
     418              :         m_libspdm_use_hash_algo, m_libspdm_use_asym_algo,
     419              :         &m_libspdm_local_certificate_chain,
     420              :         &m_libspdm_local_certificate_chain_size, NULL, NULL);
     421              : 
     422            1 :     portion_length = LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN;
     423            1 :     remainder_length =
     424            1 :         (uint16_t)(m_libspdm_local_certificate_chain_size - LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN);
     425              : 
     426            1 :     temp_buf_size = sizeof(spdm_certificate_response_t) + portion_length;
     427            1 :     spdm_response_size = temp_buf_size;
     428            1 :     spdm_response = (void *)temp_buf;
     429              : 
     430            1 :     spdm_response->header.spdm_version = SPDM_MESSAGE_VERSION_13;
     431            1 :     spdm_response->header.request_response_code = SPDM_CERTIFICATE;
     432            1 :     spdm_response->header.param1 = 0;
     433            1 :     spdm_response->header.param2 = 0;
     434            1 :     spdm_response->portion_length = portion_length;
     435            1 :     spdm_response->remainder_length = remainder_length;
     436            1 :     libspdm_copy_mem(spdm_response + 1,
     437              :                      sizeof(temp_buf) - sizeof(*spdm_response),
     438              :                      (uint8_t *)m_libspdm_local_certificate_chain,
     439              :                      portion_length);
     440              : 
     441              :     /* Sub Case 1: CertModel Value of 1 , DeviceCert model*/
     442            1 :     spdm_context->connection_info.multi_key_conn_req = true;
     443            1 :     spdm_context->encap_context.req_slot_id = 0;
     444            1 :     spdm_context->connection_info.peer_cert_info[0] = 0;
     445            1 :     spdm_context->mut_auth_cert_chain_buffer_size = 0;
     446            1 :     spdm_response->header.param2 = SPDM_CERTIFICATE_INFO_CERT_MODEL_DEVICE_CERT;
     447            1 :     libspdm_reset_message_mut_b(spdm_context);
     448              : 
     449            1 :     status = libspdm_process_encap_response_certificate(spdm_context, spdm_response_size,
     450              :                                                         spdm_response,
     451              :                                                         &need_continue);
     452              : 
     453            1 :     assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
     454            1 :     assert_int_equal(spdm_context->connection_info.peer_cert_info[0],
     455              :                      SPDM_CERTIFICATE_INFO_CERT_MODEL_DEVICE_CERT);
     456            1 :     assert_int_equal(spdm_context->mut_auth_cert_chain_buffer_size,
     457              :                      LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN);
     458            1 :     assert_memory_equal(spdm_context->mut_auth_cert_chain_buffer, m_libspdm_local_certificate_chain,
     459              :                         LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN);
     460              : 
     461              :     /* Sub Case 2: CertModel Value of 2 , AliasCert model*/
     462            1 :     spdm_context->connection_info.multi_key_conn_req = true;
     463            1 :     spdm_context->encap_context.req_slot_id = 0;
     464            1 :     spdm_context->connection_info.peer_cert_info[0] = 0;
     465            1 :     spdm_response->header.param2 = SPDM_CERTIFICATE_INFO_CERT_MODEL_ALIAS_CERT;
     466            1 :     libspdm_reset_message_mut_b(spdm_context);
     467            1 :     libspdm_zero_mem(cert_chain, sizeof(cert_chain));
     468            1 :     spdm_context->mut_auth_cert_chain_buffer_size = 0;
     469            1 :     spdm_context->mut_auth_cert_chain_buffer = cert_chain;
     470              : 
     471            1 :     status = libspdm_process_encap_response_certificate(spdm_context, spdm_response_size,
     472              :                                                         spdm_response,
     473              :                                                         &need_continue);
     474            1 :     assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
     475            1 :     assert_int_equal(spdm_context->connection_info.peer_cert_info[0],
     476              :                      SPDM_CERTIFICATE_INFO_CERT_MODEL_ALIAS_CERT);
     477            1 :     assert_int_equal(spdm_context->mut_auth_cert_chain_buffer_size,
     478              :                      LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN);
     479            1 :     assert_memory_equal(spdm_context->mut_auth_cert_chain_buffer, m_libspdm_local_certificate_chain,
     480              :                         LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN);
     481              : 
     482              :     /* Sub Case 3: CertModel Value of 3 GenericCert model , slot_id set 1
     483              :      * In all cases, the certificate model for slot 0 shall be either the device certificate model or the alias certificate model*/
     484            1 :     spdm_context->connection_info.multi_key_conn_req = true;
     485            1 :     spdm_context->encap_context.req_slot_id = 1;
     486            1 :     spdm_context->connection_info.peer_cert_info[1] = 0;
     487            1 :     spdm_context->mut_auth_cert_chain_buffer_size = 0;
     488            1 :     spdm_response->header.param1 = 1;
     489            1 :     spdm_response->header.param2 = SPDM_CERTIFICATE_INFO_CERT_MODEL_GENERIC_CERT;
     490            1 :     libspdm_reset_message_mut_b(spdm_context);
     491            1 :     libspdm_zero_mem(cert_chain, sizeof(cert_chain));
     492            1 :     spdm_context->mut_auth_cert_chain_buffer_size = 0;
     493            1 :     spdm_context->mut_auth_cert_chain_buffer = cert_chain;
     494              : 
     495            1 :     status = libspdm_process_encap_response_certificate(spdm_context, spdm_response_size,
     496              :                                                         spdm_response,
     497              :                                                         &need_continue);
     498            1 :     assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
     499            1 :     assert_int_equal(spdm_context->connection_info.peer_cert_info[1],
     500              :                      SPDM_CERTIFICATE_INFO_CERT_MODEL_GENERIC_CERT);
     501            1 :     assert_int_equal(spdm_context->mut_auth_cert_chain_buffer_size,
     502              :                      LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN);
     503            1 :     assert_memory_equal(spdm_context->mut_auth_cert_chain_buffer, m_libspdm_local_certificate_chain,
     504              :                         LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN);
     505              : 
     506              :     /* Sub Case 4: CertModel Value of 3 , GenericCert model ,slot_id set 0
     507              :      * In all cases, the certificate model for slot 0 shall be either the device certificate model or the alias certificate model*/
     508            1 :     spdm_context->connection_info.multi_key_conn_req = true;
     509            1 :     spdm_context->encap_context.req_slot_id = 0;
     510            1 :     spdm_context->connection_info.peer_cert_info[0] = 0;
     511            1 :     spdm_context->mut_auth_cert_chain_buffer_size = 0;
     512            1 :     spdm_response->header.param1 = 0;
     513            1 :     spdm_response->header.param2 = SPDM_CERTIFICATE_INFO_CERT_MODEL_GENERIC_CERT;
     514            1 :     libspdm_reset_message_mut_b(spdm_context);
     515            1 :     libspdm_zero_mem(cert_chain, sizeof(cert_chain));
     516            1 :     spdm_context->mut_auth_cert_chain_buffer_size = 0;
     517            1 :     spdm_context->mut_auth_cert_chain_buffer = cert_chain;
     518              : 
     519            1 :     status = libspdm_process_encap_response_certificate(spdm_context, spdm_response_size,
     520              :                                                         spdm_response,
     521              :                                                         &need_continue);
     522            1 :     assert_int_equal(status, LIBSPDM_STATUS_INVALID_MSG_FIELD);
     523            1 :     assert_int_equal(spdm_context->connection_info.peer_cert_info[0], 0);
     524              : 
     525              :     /* Sub Case 5: CertModel Value of 0 , MULTI_KEY_CONN_REQ is true*/
     526              :     /* Value of 0 indicates either that the certificate slot does not contain any certificates or that the corresponding
     527              :      * MULTI_KEY_CONN_REQ or MULTI_KEY_CONN_RSP is false. */
     528            1 :     spdm_context->connection_info.multi_key_conn_req = true;
     529            1 :     spdm_context->encap_context.req_slot_id = 0;
     530            1 :     spdm_context->connection_info.peer_cert_info[0] = 0;
     531            1 :     spdm_context->mut_auth_cert_chain_buffer_size = 0;
     532            1 :     spdm_response->header.param2 = SPDM_CERTIFICATE_INFO_CERT_MODEL_NONE;
     533            1 :     libspdm_reset_message_mut_b(spdm_context);
     534            1 :     libspdm_zero_mem(cert_chain, sizeof(cert_chain));
     535            1 :     spdm_context->mut_auth_cert_chain_buffer_size = 0;
     536            1 :     spdm_context->mut_auth_cert_chain_buffer = cert_chain;
     537              : 
     538            1 :     status = libspdm_process_encap_response_certificate(spdm_context, spdm_response_size,
     539              :                                                         spdm_response,
     540              :                                                         &need_continue);
     541            1 :     assert_int_equal(status, LIBSPDM_STATUS_INVALID_MSG_FIELD);
     542            1 :     assert_int_equal(spdm_context->connection_info.peer_cert_info[0],
     543              :                      SPDM_CERTIFICATE_INFO_CERT_MODEL_NONE);
     544              : 
     545              :     /* Sub Case 6: CertModel Value of 0 , MULTI_KEY_CONN_REQ is false*/
     546              :     /* Value of 0 indicates either that the certificate slot does not contain any certificates or that the corresponding
     547              :      * MULTI_KEY_CONN_REQ or MULTI_KEY_CONN_RSP is false. */
     548            1 :     spdm_context->connection_info.multi_key_conn_req = false;
     549            1 :     spdm_context->encap_context.req_slot_id = 0;
     550            1 :     spdm_context->connection_info.peer_cert_info[0] = 0;
     551            1 :     spdm_context->mut_auth_cert_chain_buffer_size = 0;
     552            1 :     spdm_response->header.param2 = SPDM_CERTIFICATE_INFO_CERT_MODEL_NONE;
     553            1 :     libspdm_reset_message_mut_b(spdm_context);
     554            1 :     libspdm_zero_mem(cert_chain, sizeof(cert_chain));
     555            1 :     spdm_context->mut_auth_cert_chain_buffer_size = 0;
     556            1 :     spdm_context->mut_auth_cert_chain_buffer = cert_chain;
     557              : 
     558            1 :     status = libspdm_process_encap_response_certificate(spdm_context, spdm_response_size,
     559              :                                                         spdm_response,
     560              :                                                         &need_continue);
     561            1 :     assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
     562            1 :     assert_int_equal(spdm_context->connection_info.peer_cert_info[0],
     563              :                      SPDM_CERTIFICATE_INFO_CERT_MODEL_NONE);
     564            1 :     assert_int_equal(spdm_context->mut_auth_cert_chain_buffer_size,
     565              :                      LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN);
     566            1 :     assert_memory_equal(spdm_context->mut_auth_cert_chain_buffer, m_libspdm_local_certificate_chain,
     567              :                         LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN);
     568              : 
     569            1 :     free(data);
     570            1 :     free(m_libspdm_local_certificate_chain);
     571            1 :     m_libspdm_local_certificate_chain = NULL;
     572            1 :     m_libspdm_local_certificate_chain_size = 0;
     573            1 : }
     574              : 
     575            1 : int spdm_rsp_encap_get_certificate_test(void)
     576              : {
     577            1 :     const struct CMUnitTest test_cases[] = {
     578              :         /* Success Case*/
     579              :         cmocka_unit_test(rsp_encap_get_certificate_case1),
     580              :         /* Bad request size ,remaining length is 0*/
     581              :         cmocka_unit_test(rsp_encap_get_certificate_case2),
     582              :         /* Error response: SPDM_ERROR_CODE_INVALID_REQUEST*/
     583              :         cmocka_unit_test(rsp_encap_get_certificate_case2),
     584              :         /* Fail response: spdm_request.offset + spdm_response.portion_length + spdm_response.remainder_length !=
     585              :          * total_responder_cert_chain_buffer_length.*/
     586              :         cmocka_unit_test(rsp_encap_get_certificate_case3),
     587              :         /* Fail response: responder return portion_length > spdm_request.length*/
     588              :         cmocka_unit_test(rsp_encap_get_certificate_case4),
     589              :         /* check request attributes and response attributes*/
     590              :         cmocka_unit_test(rsp_encap_get_certificate_case5),
     591              :     };
     592              : 
     593            1 :     libspdm_test_context_t test_context = {
     594              :         LIBSPDM_TEST_CONTEXT_VERSION,
     595              :         false,
     596              :     };
     597              : 
     598            1 :     libspdm_setup_test_context(&test_context);
     599              : 
     600            1 :     return cmocka_run_group_tests(test_cases,
     601              :                                   libspdm_unit_test_group_setup,
     602              :                                   libspdm_unit_test_group_teardown);
     603              : }
     604              : 
     605              : #endif /* (LIBSPDM_ENABLE_CAPABILITY_MUT_AUTH_CAP) && (...) */
        

Generated by: LCOV version 2.0-1