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