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 :
7 : #include "spdm_unit_test.h"
8 : #include "internal/libspdm_requester_lib.h"
9 :
10 : #if (LIBSPDM_ENABLE_CAPABILITY_MUT_AUTH_CAP) && (LIBSPDM_ENABLE_CAPABILITY_ENCAP_CAP) && \
11 : (LIBSPDM_ENABLE_CAPABILITY_CERT_CAP)
12 :
13 : /* #define TEST_DEBUG*/
14 : #ifdef TEST_DEBUG
15 : #define TEST_DEBUG_PRINT(format, ...) printf(format, ## __VA_ARGS__)
16 : #else
17 : #define TEST_DEBUG_PRINT(...)
18 : #endif
19 :
20 : spdm_get_certificate_request_t m_spdm_get_certificate_request1 = {
21 : {SPDM_MESSAGE_VERSION_11, SPDM_GET_CERTIFICATE, 0, 0},
22 : 0,
23 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN
24 : };
25 : size_t m_spdm_get_certificate_request1_size =
26 : sizeof(m_spdm_get_certificate_request1);
27 :
28 : spdm_get_certificate_request_t m_spdm_get_certificate_request3 = {
29 : {SPDM_MESSAGE_VERSION_11, SPDM_GET_CERTIFICATE, 0, 0}, 0, 0
30 : };
31 : size_t m_spdm_get_certificate_request3_size =
32 : sizeof(m_spdm_get_certificate_request3);
33 :
34 : spdm_get_certificate_request_t m_spdm_get_certificate_request4 = {
35 : {SPDM_MESSAGE_VERSION_13, SPDM_GET_CERTIFICATE, 0, 0},
36 : 0,
37 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN
38 : };
39 : size_t m_spdm_get_certificate_request4_size =
40 : sizeof(m_spdm_get_certificate_request4);
41 :
42 : /**
43 : * Test 1: request the first LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN bytes of the
44 : * certificate chain Expected Behavior: generate a correctly formed Certificate
45 : * message, including its portion_length and remainder_length fields
46 : **/
47 1 : void libspdm_test_requester_encap_certificate_case1(void **state)
48 : {
49 : libspdm_return_t status;
50 : libspdm_test_context_t *spdm_test_context;
51 : libspdm_context_t *spdm_context;
52 : size_t response_size;
53 : uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
54 : spdm_certificate_response_t *spdm_response;
55 : void *data;
56 : size_t data_size;
57 :
58 1 : spdm_test_context = *state;
59 1 : spdm_context = spdm_test_context->spdm_context;
60 1 : spdm_test_context->case_id = 0x1;
61 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_11
62 : << SPDM_VERSION_NUMBER_SHIFT_BIT;
63 1 : spdm_context->connection_info.connection_state =
64 : LIBSPDM_CONNECTION_STATE_AFTER_DIGESTS;
65 1 : spdm_context->local_context.capability.flags |=
66 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
67 1 : spdm_context->connection_info.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
68 1 : libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
69 : m_libspdm_use_asym_algo,
70 : &data, &data_size, NULL, NULL);
71 1 : spdm_context->local_context.local_cert_chain_provision[0] = data;
72 1 : spdm_context->local_context.local_cert_chain_provision_size[0] = data_size;
73 :
74 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
75 : spdm_context->transcript.message_m.buffer_size =
76 : spdm_context->transcript.message_m.max_buffer_size;
77 : #endif
78 :
79 1 : response_size = sizeof(response);
80 1 : status = libspdm_get_encap_response_certificate(
81 : spdm_context, m_spdm_get_certificate_request1_size,
82 : &m_spdm_get_certificate_request1, &response_size, response);
83 :
84 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
85 1 : assert_int_equal(response_size, sizeof(spdm_certificate_response_t) +
86 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN);
87 1 : spdm_response = (void *)response;
88 1 : assert_int_equal(spdm_response->header.request_response_code,
89 : SPDM_CERTIFICATE);
90 1 : assert_int_equal(spdm_response->header.param1, 0);
91 1 : assert_int_equal(spdm_response->portion_length,
92 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN);
93 1 : assert_int_equal(spdm_response->remainder_length,
94 : data_size - LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN);
95 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
96 : assert_int_equal(spdm_context->transcript.message_m.buffer_size, 0);
97 : #endif
98 1 : free(data);
99 1 : }
100 :
101 : /**
102 : * Test 2:
103 : * Expected Behavior:
104 : **/
105 1 : void libspdm_test_requester_encap_certificate_case2(void **state)
106 : {
107 1 : }
108 :
109 : /**
110 : * Test 3: request length at the boundary of maximum integer values, while
111 : * keeping offset 0 Expected Behavior: generate correctly formed Certificate
112 : * messages, including its portion_length and remainder_length fields
113 : **/
114 0 : void libspdm_test_requester_encap_certificate_case3(void **state)
115 : {
116 : libspdm_return_t status;
117 : libspdm_test_context_t *spdm_test_context;
118 : libspdm_context_t *spdm_context;
119 : size_t response_size;
120 : uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
121 : spdm_certificate_response_t *spdm_response;
122 : void *data;
123 : size_t data_size;
124 :
125 : /* Testing Lengths at the boundary of maximum integer values*/
126 0 : uint16_t test_lengths[] = {
127 : 0,
128 : 0x7F,
129 : (uint16_t)(0x7F + 1),
130 : 0xFF,
131 : 0x7FFF,
132 : (uint16_t)(0x7FFF + 1),
133 : 0xFFFF,
134 : };
135 : uint16_t expected_chunk_size;
136 :
137 : /* Setting up the spdm_context and loading a sample certificate chain*/
138 0 : spdm_test_context = *state;
139 0 : spdm_context = spdm_test_context->spdm_context;
140 0 : spdm_test_context->case_id = 0x3;
141 0 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_11
142 : << SPDM_VERSION_NUMBER_SHIFT_BIT;
143 0 : spdm_context->local_context.capability.flags |=
144 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
145 0 : spdm_context->connection_info.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
146 0 : libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
147 : m_libspdm_use_asym_algo,
148 : &data, &data_size, NULL, NULL);
149 0 : spdm_context->local_context.local_cert_chain_provision[0] = data;
150 0 : spdm_context->local_context.local_cert_chain_provision_size[0] = data_size;
151 :
152 : /* This tests considers only offset = 0, other tests vary offset value*/
153 0 : m_spdm_get_certificate_request3.offset = 0;
154 :
155 0 : for (int i = 0; i < sizeof(test_lengths) / sizeof(test_lengths[0]); i++)
156 : {
157 : TEST_DEBUG_PRINT("i:%d test_lengths[i]:%u\n", i, test_lengths[i]);
158 0 : m_spdm_get_certificate_request3.length = test_lengths[i];
159 : /* Expected received length is limited by LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN
160 : * (implementation specific?)*/
161 0 : expected_chunk_size = LIBSPDM_MIN(m_spdm_get_certificate_request3.length,
162 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN);
163 :
164 : /* resetting an internal buffer to avoid overflow and prevent tests to
165 : * succeed*/
166 0 : libspdm_reset_message_mut_b(spdm_context);
167 0 : response_size = sizeof(response);
168 0 : m_spdm_get_certificate_request3_size =
169 : sizeof(m_spdm_get_certificate_request3);
170 0 : status = libspdm_get_encap_response_certificate(
171 : spdm_context, m_spdm_get_certificate_request3_size,
172 : &m_spdm_get_certificate_request3, &response_size, response);
173 0 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
174 0 : assert_int_equal(response_size,
175 : sizeof(spdm_certificate_response_t) + expected_chunk_size);
176 0 : spdm_response = (void *)response;
177 0 : assert_int_equal(spdm_response->header.request_response_code,
178 : SPDM_CERTIFICATE);
179 0 : assert_int_equal(spdm_response->header.param1, 0);
180 0 : assert_int_equal(spdm_response->portion_length, expected_chunk_size);
181 0 : assert_int_equal(spdm_response->remainder_length,
182 : data_size - expected_chunk_size);
183 : }
184 0 : free(data);
185 0 : }
186 :
187 : /**
188 : * Test 4: request offset at the boundary of maximum integer values, while
189 : * keeping length 0 Expected Behavior: generate correctly formed Certificate
190 : * messages, including its portion_length and remainder_length fields
191 : **/
192 1 : void libspdm_test_requester_encap_certificate_case4(void **state)
193 : {
194 : libspdm_return_t status;
195 : libspdm_test_context_t *spdm_test_context;
196 : libspdm_context_t *spdm_context;
197 : size_t response_size;
198 : uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
199 : spdm_certificate_response_t *spdm_response;
200 : spdm_error_response_t *spdm_responseError;
201 : void *data;
202 : size_t data_size;
203 :
204 : /* Testing offsets at the boundary of maximum integer values and at the
205 : * boundary of certificate length (first three positions)*/
206 1 : uint16_t test_offsets[] = {(uint16_t)(-1),
207 : 0,
208 : +1,
209 : 0,
210 : 0x7F,
211 : (uint16_t)(0x7F + 1),
212 : 0xFF,
213 : 0x7FFF,
214 : (uint16_t)(0x7FFF + 1),
215 : 0xFFFF,
216 : (uint16_t)(-1)};
217 :
218 : /* Setting up the spdm_context and loading a sample certificate chain*/
219 1 : spdm_test_context = *state;
220 1 : spdm_context = spdm_test_context->spdm_context;
221 1 : spdm_test_context->case_id = 0x4;
222 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_11
223 : << SPDM_VERSION_NUMBER_SHIFT_BIT;
224 1 : spdm_context->local_context.capability.flags |=
225 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
226 1 : spdm_context->connection_info.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
227 1 : libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
228 : m_libspdm_use_asym_algo,
229 : &data, &data_size, NULL, NULL);
230 1 : spdm_context->local_context.local_cert_chain_provision[0] = data;
231 1 : spdm_context->local_context.local_cert_chain_provision_size[0] = data_size;
232 :
233 : /* This tests considers only length = 0, other tests vary length value*/
234 1 : m_spdm_get_certificate_request3.length = 0;
235 : /* Setting up offset values at the boundary of certificate length*/
236 1 : test_offsets[0] = (uint16_t)(test_offsets[0] + data_size);
237 1 : test_offsets[1] = (uint16_t)(test_offsets[1] + data_size);
238 1 : test_offsets[2] = (uint16_t)(test_offsets[2] + data_size);
239 :
240 12 : for (int i = 0; i < sizeof(test_offsets) / sizeof(test_offsets[0]); i++)
241 : {
242 : TEST_DEBUG_PRINT("i:%d test_offsets[i]:%u\n", i, test_offsets[i]);
243 11 : m_spdm_get_certificate_request3.offset = test_offsets[i];
244 :
245 : /* resetting an internal buffer to avoid overflow and prevent tests to
246 : * succeed*/
247 11 : libspdm_reset_message_mut_b(spdm_context);
248 11 : response_size = sizeof(response);
249 11 : status = libspdm_get_encap_response_certificate(
250 : spdm_context, m_spdm_get_certificate_request3_size,
251 : &m_spdm_get_certificate_request3, &response_size, response);
252 11 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
253 :
254 11 : if (m_spdm_get_certificate_request3.offset >= data_size) {
255 : /* A too long of an offset should return an error*/
256 6 : spdm_responseError = (void *)response;
257 6 : assert_int_equal(spdm_responseError->header.request_response_code,
258 : SPDM_ERROR);
259 6 : assert_int_equal(spdm_responseError->header.param1,
260 : SPDM_ERROR_CODE_INVALID_REQUEST);
261 : } else {
262 : /* Otherwise it should work properly, considering length = 0*/
263 5 : assert_int_equal(response_size, sizeof(spdm_certificate_response_t));
264 5 : spdm_response = (void *)response;
265 5 : assert_int_equal(spdm_response->header.request_response_code,
266 : SPDM_CERTIFICATE);
267 5 : assert_int_equal(spdm_response->header.param1, 0);
268 5 : assert_int_equal(spdm_response->portion_length, 0);
269 5 : assert_int_equal(
270 : spdm_response->remainder_length,
271 : (uint16_t)(data_size - m_spdm_get_certificate_request3.offset));
272 : }
273 : }
274 1 : free(data);
275 1 : }
276 :
277 : /**
278 : * Test 5: request LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN bytes of long certificate
279 : * chains, with the largest valid offset Expected Behavior: generate correctly
280 : * formed Certificate messages, including its portion_length and remainder_length
281 : * fields
282 : **/
283 1 : void libspdm_test_requester_encap_certificate_case5(void **state)
284 : {
285 : libspdm_return_t status;
286 : libspdm_test_context_t *spdm_test_context;
287 : libspdm_context_t *spdm_context;
288 : size_t response_size;
289 : uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
290 : spdm_certificate_response_t *spdm_response;
291 : spdm_error_response_t *spdm_responseError;
292 : void *data;
293 : size_t data_size;
294 :
295 1 : uint16_t test_cases[] = {LIBSPDM_TEST_CERT_MAXINT16, LIBSPDM_TEST_CERT_MAXUINT16};
296 :
297 : size_t expected_chunk_size;
298 : size_t expected_remainder;
299 :
300 : /* Setting up the spdm_context and loading a sample certificate chain*/
301 1 : spdm_test_context = *state;
302 1 : spdm_context = spdm_test_context->spdm_context;
303 1 : spdm_test_context->case_id = 0x5;
304 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_11
305 : << SPDM_VERSION_NUMBER_SHIFT_BIT;
306 1 : spdm_context->local_context.capability.flags |=
307 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
308 1 : spdm_context->connection_info.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
309 :
310 1 : m_spdm_get_certificate_request3.length = LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN;
311 :
312 3 : for (int i = 0; i < sizeof(test_cases) / sizeof(test_cases[0]); i++)
313 : {
314 2 : libspdm_read_responder_public_certificate_chain_by_size(
315 : /*MAXUINT16_CERT signature_algo is SHA256RSA */
316 : m_libspdm_use_hash_algo, SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_2048,
317 2 : test_cases[i], &data, &data_size, NULL, NULL);
318 :
319 2 : spdm_context->local_context.local_cert_chain_provision[0] = data;
320 2 : spdm_context->local_context.local_cert_chain_provision_size[0] = data_size;
321 :
322 2 : m_spdm_get_certificate_request3.offset =
323 2 : (uint16_t)(LIBSPDM_MIN(data_size - 1, 0xFFFF));
324 : TEST_DEBUG_PRINT("data_size: %u\n", data_size);
325 : TEST_DEBUG_PRINT("m_spdm_get_certificate_request3.offset: %u\n",
326 : m_spdm_get_certificate_request3.offset);
327 : TEST_DEBUG_PRINT("m_spdm_get_certificate_request3.length: %u\n",
328 : m_spdm_get_certificate_request3.length);
329 : TEST_DEBUG_PRINT("offset + length: %u\n",
330 : m_spdm_get_certificate_request3.offset +
331 : m_spdm_get_certificate_request3.length);
332 :
333 : /* resetting an internal buffer to avoid overflow and prevent tests to
334 : * succeed*/
335 2 : libspdm_reset_message_mut_b(spdm_context);
336 2 : response_size = sizeof(response);
337 2 : status = libspdm_get_encap_response_certificate(
338 : spdm_context, m_spdm_get_certificate_request3_size,
339 : &m_spdm_get_certificate_request3, &response_size, response);
340 2 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
341 :
342 : /* Expected received length is limited by LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN
343 : * and by the remaining length*/
344 2 : expected_chunk_size =
345 2 : (uint16_t)(LIBSPDM_MIN(m_spdm_get_certificate_request3.length,
346 : data_size - m_spdm_get_certificate_request3.offset));
347 2 : expected_chunk_size =
348 : LIBSPDM_MIN(expected_chunk_size, LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN);
349 : /* Expected certificate length left*/
350 2 : expected_remainder =
351 2 : (uint16_t)(data_size - m_spdm_get_certificate_request3.offset -
352 : expected_chunk_size);
353 :
354 : TEST_DEBUG_PRINT("expected_chunk_size %u\n", expected_chunk_size);
355 : TEST_DEBUG_PRINT("expected_remainder %u\n", expected_remainder);
356 :
357 2 : if (expected_remainder > 0xFFFF || expected_chunk_size > 0xFFFF) {
358 0 : spdm_responseError = (void *)response;
359 0 : assert_int_equal(spdm_responseError->header.request_response_code,
360 : SPDM_ERROR);
361 0 : assert_int_equal(spdm_responseError->header.param1,
362 : SPDM_ERROR_CODE_INVALID_REQUEST);
363 : } else {
364 2 : assert_int_equal(response_size, sizeof(spdm_certificate_response_t) +
365 : expected_chunk_size);
366 2 : spdm_response = (void *)response;
367 2 : assert_int_equal(spdm_response->header.request_response_code,
368 : SPDM_CERTIFICATE);
369 2 : assert_int_equal(spdm_response->header.param1, 0);
370 2 : assert_int_equal(spdm_response->portion_length, expected_chunk_size);
371 2 : assert_int_equal(spdm_response->remainder_length, expected_remainder);
372 : }
373 :
374 : TEST_DEBUG_PRINT("\n");
375 :
376 2 : spdm_context->local_context.local_cert_chain_provision[0] = NULL;
377 2 : spdm_context->local_context.local_cert_chain_provision_size[0] = 0;
378 2 : free(data);
379 : }
380 1 : }
381 :
382 : /**
383 : * Test 6: request a whole certificate chain byte by byte
384 : * Expected Behavior: generate correctly formed Certificate messages, including
385 : * its portion_length and remainder_length fields
386 : **/
387 1 : void libspdm_test_requester_encap_certificate_case6(void **state)
388 : {
389 : libspdm_return_t status;
390 : libspdm_test_context_t *spdm_test_context;
391 : libspdm_context_t *spdm_context;
392 : size_t response_size;
393 : uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
394 : spdm_certificate_response_t *spdm_response;
395 : void *data;
396 : size_t data_size;
397 : uint16_t expected_chunk_size;
398 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
399 : size_t count;
400 : #endif
401 : /* Setting up the spdm_context and loading a sample certificate chain*/
402 1 : spdm_test_context = *state;
403 1 : spdm_context = spdm_test_context->spdm_context;
404 1 : spdm_test_context->case_id = 0x6;
405 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_11
406 : << SPDM_VERSION_NUMBER_SHIFT_BIT;
407 1 : spdm_context->local_context.capability.flags |=
408 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
409 1 : spdm_context->connection_info.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
410 1 : libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
411 : m_libspdm_use_asym_algo,
412 : &data, &data_size, NULL, NULL);
413 1 : spdm_context->local_context.local_cert_chain_provision[0] = data;
414 1 : spdm_context->local_context.local_cert_chain_provision_size[0] = data_size;
415 :
416 : /* This tests considers only length = 1*/
417 1 : m_spdm_get_certificate_request3.length = 1;
418 1 : expected_chunk_size = 1;
419 :
420 : /* resetting an internal buffer to avoid overflow and prevent tests to
421 : * succeed*/
422 1 : libspdm_reset_message_mut_b(spdm_context);
423 :
424 1 : spdm_response = NULL;
425 1391 : for (size_t offset = 0; offset < data_size; offset++)
426 : {
427 : TEST_DEBUG_PRINT("offset:%u \n", offset);
428 1390 : m_spdm_get_certificate_request3.offset = (uint16_t)offset;
429 :
430 1390 : response_size = sizeof(response);
431 1390 : status = libspdm_get_encap_response_certificate(
432 : spdm_context, m_spdm_get_certificate_request3_size,
433 : &m_spdm_get_certificate_request3, &response_size, response);
434 1390 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
435 1390 : spdm_response = (void *)response;
436 : /* It may fail because the spdm does not support too many messages.
437 : * assert_int_equal (spdm_response->header.request_response_code,
438 : * SPDM_CERTIFICATE);*/
439 1390 : if (spdm_response->header.request_response_code == SPDM_CERTIFICATE) {
440 1390 : assert_int_equal(spdm_response->header.request_response_code,
441 : SPDM_CERTIFICATE);
442 1390 : assert_int_equal(response_size, sizeof(spdm_certificate_response_t) +
443 : expected_chunk_size);
444 1390 : assert_int_equal(spdm_response->header.param1, 0);
445 1390 : assert_int_equal(spdm_response->portion_length, expected_chunk_size);
446 1390 : assert_int_equal(spdm_response->remainder_length,
447 : data_size - offset - expected_chunk_size);
448 1390 : assert_int_equal(((uint8_t *)data)[offset],
449 : (response + sizeof(spdm_certificate_response_t))[0]);
450 : } else {
451 0 : assert_int_equal(spdm_response->header.request_response_code, SPDM_ERROR);
452 0 : break;
453 : }
454 : }
455 1 : if (spdm_response != NULL) {
456 1 : if (spdm_response->header.request_response_code == SPDM_CERTIFICATE) {
457 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
458 : count = (data_size + m_spdm_get_certificate_request3.length - 1) /
459 : m_spdm_get_certificate_request3.length;
460 : assert_int_equal(spdm_context->transcript.message_mut_b.buffer_size,
461 : sizeof(spdm_get_certificate_request_t) * count +
462 : sizeof(spdm_certificate_response_t) * count +
463 : data_size);
464 : #endif
465 : }
466 : }
467 1 : free(data);
468 1 : }
469 :
470 : /**
471 : * Test 7: check request attributes and response attributes , SlotSizeRequested=1b the Offset and Length fields in the
472 : * GET_CERTIFICATE request shall be ignored by the Responder
473 : * Expected Behavior: generate a correctly formed Certificate message, including its portion_length and remainder_length fields
474 : **/
475 1 : void libspdm_test_requester_encap_certificate_case7(void **state)
476 : {
477 : libspdm_return_t status;
478 : libspdm_test_context_t *spdm_test_context;
479 : libspdm_context_t *spdm_context;
480 : size_t response_size;
481 : uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
482 : spdm_certificate_response_t *spdm_response;
483 : void *data;
484 : size_t data_size;
485 :
486 1 : spdm_test_context = *state;
487 1 : spdm_context = spdm_test_context->spdm_context;
488 1 : spdm_test_context->case_id = 0x7;
489 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_13
490 : << SPDM_VERSION_NUMBER_SHIFT_BIT;
491 1 : spdm_context->connection_info.connection_state =
492 : LIBSPDM_CONNECTION_STATE_AFTER_DIGESTS;
493 1 : spdm_context->local_context.capability.flags = 0;
494 1 : spdm_context->local_context.capability.flags |=
495 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
496 1 : spdm_context->connection_info.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
497 1 : libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
498 : m_libspdm_use_asym_algo,
499 : &data, &data_size, NULL, NULL);
500 1 : spdm_context->local_context.local_cert_chain_provision[0] = data;
501 1 : spdm_context->local_context.local_cert_chain_provision_size[0] = data_size;
502 :
503 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
504 : spdm_context->transcript.message_mut_b.buffer_size = 0;
505 : #endif
506 :
507 : /* When SlotSizeRequested=1b , the Offset and Length fields in the GET_CERTIFICATE request shall be ignored by the Responder */
508 1 : m_spdm_get_certificate_request4.header.param2 =
509 : SPDM_GET_CERTIFICATE_REQUEST_ATTRIBUTES_SLOT_SIZE_REQUESTED;
510 1 : m_spdm_get_certificate_request4.length = LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN;
511 1 : m_spdm_get_certificate_request4.offset = 0xFF;
512 :
513 1 : response_size = sizeof(response);
514 1 : status = libspdm_get_encap_response_certificate(
515 : spdm_context, m_spdm_get_certificate_request4_size,
516 : &m_spdm_get_certificate_request4, &response_size, response);
517 :
518 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
519 1 : assert_int_equal(response_size, sizeof(spdm_certificate_response_t));
520 1 : spdm_response = (void *)response;
521 1 : assert_int_equal(spdm_response->header.request_response_code,
522 : SPDM_CERTIFICATE);
523 1 : assert_int_equal(spdm_response->header.param1, 0);
524 1 : assert_int_equal(spdm_response->portion_length,0);
525 1 : assert_int_equal(spdm_response->remainder_length, data_size);
526 :
527 1 : free(data);
528 1 : }
529 :
530 1 : int libspdm_requester_encap_certificate_test_main(void)
531 : {
532 1 : const struct CMUnitTest spdm_requester_encap_certificate_tests[] = {
533 : /* Success Case*/
534 : cmocka_unit_test(libspdm_test_requester_encap_certificate_case1),
535 : /* Can be populated with new test.*/
536 : cmocka_unit_test(libspdm_test_requester_encap_certificate_case2),
537 : /* Tests varying offset*/
538 : cmocka_unit_test(libspdm_test_requester_encap_certificate_case4),
539 : /* Tests large certificate chains*/
540 : cmocka_unit_test(libspdm_test_requester_encap_certificate_case5),
541 : /* Requests byte by byte*/
542 : cmocka_unit_test(libspdm_test_requester_encap_certificate_case6),
543 : /* check request attributes and response attributes*/
544 : cmocka_unit_test(libspdm_test_requester_encap_certificate_case7),
545 : };
546 :
547 1 : libspdm_test_context_t test_context = {
548 : LIBSPDM_TEST_CONTEXT_VERSION,
549 : false,
550 : };
551 :
552 1 : libspdm_setup_test_context(&test_context);
553 :
554 1 : return cmocka_run_group_tests(spdm_requester_encap_certificate_tests,
555 : libspdm_unit_test_group_setup,
556 : libspdm_unit_test_group_teardown);
557 : }
558 :
559 : #endif /* (LIBSPDM_ENABLE_CAPABILITY_MUT_AUTH_CAP) && (..) */
|