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) && (...) */
|