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