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 % 281 271
Test Date: 2025-12-21 08:10:27 Functions: 100.0 % 6 6

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

Generated by: LCOV version 2.0-1