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