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 : void test_spdm_responder_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 : void test_spdm_responder_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 : void test_spdm_responder_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 : void test_spdm_responder_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 :
308 1 : spdm_test_context = *state;
309 1 : spdm_context = spdm_test_context->spdm_context;
310 1 : spdm_test_context->case_id = 0x4;
311 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_10 <<
312 : SPDM_VERSION_NUMBER_SHIFT_BIT;
313 1 : spdm_context->connection_info.capability.flags |=
314 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
315 1 : if (!libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
316 : m_libspdm_use_asym_algo, &data,
317 : &data_size, &hash, &hash_size)) {
318 0 : assert(false);
319 : }
320 1 : if (!libspdm_x509_get_cert_from_cert_chain(
321 1 : (uint8_t *)data + sizeof(spdm_cert_chain_t) + hash_size,
322 1 : data_size - sizeof(spdm_cert_chain_t) - hash_size, 0, &root_cert, &root_cert_size)) {
323 0 : assert(false);
324 : }
325 1 : libspdm_dump_hex(
326 : root_cert,
327 : root_cert_size);
328 1 : spdm_context->local_context.peer_root_cert_provision_size[0] =
329 : root_cert_size;
330 1 : spdm_context->local_context.peer_root_cert_provision[0] = root_cert;
331 1 : libspdm_reset_message_b(spdm_context);
332 1 : spdm_context->connection_info.algorithm.base_hash_algo =
333 : m_libspdm_use_hash_algo;
334 :
335 1 : spdm_context->connection_info.algorithm.req_base_asym_alg =
336 : SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P256;
337 :
338 1 : if (m_libspdm_local_certificate_chain == NULL) {
339 1 : libspdm_read_responder_public_certificate_chain(
340 : m_libspdm_use_hash_algo, m_libspdm_use_asym_algo,
341 : &m_libspdm_local_certificate_chain,
342 : &m_libspdm_local_certificate_chain_size, NULL, NULL);
343 : }
344 :
345 1 : portion_length = LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN + 1; /* Fail response: responder return portion_length > spdm_request.length*/
346 1 : remainder_length =
347 1 : (uint16_t)(m_libspdm_local_certificate_chain_size - 1 -
348 1 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN * (calling_index + 1));
349 :
350 1 : temp_buf_size =
351 1 : sizeof(spdm_certificate_response_t) + portion_length;
352 1 : spdm_response_size = temp_buf_size;
353 1 : spdm_response = (void *)temp_buf;
354 :
355 1 : spdm_response->header.spdm_version = SPDM_MESSAGE_VERSION_10;
356 1 : spdm_response->header.request_response_code = SPDM_CERTIFICATE;
357 1 : spdm_response->header.param1 = 0;
358 1 : spdm_response->header.param2 = 0;
359 1 : spdm_response->portion_length = portion_length;
360 1 : spdm_response->remainder_length = remainder_length;
361 1 : libspdm_copy_mem(spdm_response + 1,
362 : sizeof(temp_buf) - sizeof(*spdm_response),
363 1 : (uint8_t *)m_libspdm_local_certificate_chain +
364 1 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN * calling_index,
365 : portion_length);
366 :
367 1 : free(m_libspdm_local_certificate_chain);
368 1 : m_libspdm_local_certificate_chain = NULL;
369 1 : m_libspdm_local_certificate_chain_size = 0;
370 :
371 1 : status = libspdm_process_encap_response_certificate(spdm_context, spdm_response_size,
372 : spdm_response,
373 : &need_continue);
374 1 : assert_int_equal(status, LIBSPDM_STATUS_INVALID_MSG_FIELD);
375 :
376 1 : spdm_context->mut_auth_cert_chain_buffer_size = 0;
377 1 : free(data);
378 1 : }
379 :
380 : /**
381 : * Test 5: check request attributes and response attributes ,
382 : * Set CertModel to determine whether it meets expectations
383 : * Expected Behavior: requester returns the status LIBSPDM_STATUS_SUCCESS
384 : * Expected Behavior: CertModel is GenericCert model and slot 0 , returns a status of RETURN_DEVICE_ERROR.
385 : * Expected Behavior: CertModel Value of 0 and certificate chain is valid, returns a status of RETURN_DEVICE_ERROR.
386 : **/
387 1 : void test_spdm_responder_encap_get_certificate_case5(void **state)
388 : {
389 : libspdm_return_t status;
390 : libspdm_test_context_t *spdm_test_context;
391 : libspdm_context_t *spdm_context;
392 : void *data;
393 : size_t data_size;
394 : void *hash;
395 : size_t hash_size;
396 : const uint8_t *root_cert;
397 : size_t root_cert_size;
398 : bool need_continue;
399 : spdm_certificate_response_t *spdm_response;
400 : uint8_t temp_buf[LIBSPDM_MAX_SPDM_MSG_SIZE];
401 : size_t temp_buf_size;
402 : uint8_t cert_chain[LIBSPDM_MAX_CERT_CHAIN_SIZE];
403 : uint16_t portion_length;
404 : uint16_t remainder_length;
405 : size_t spdm_response_size;
406 :
407 1 : spdm_test_context = *state;
408 1 : spdm_context = spdm_test_context->spdm_context;
409 1 : spdm_test_context->case_id = 0x5;
410 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_13 <<
411 : SPDM_VERSION_NUMBER_SHIFT_BIT;
412 1 : spdm_context->connection_info.capability.flags = 0;
413 1 : spdm_context->connection_info.capability.flags |=
414 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
415 1 : spdm_context->connection_info.algorithm.base_hash_algo =
416 : m_libspdm_use_hash_algo;
417 1 : spdm_context->connection_info.algorithm.req_base_asym_alg =
418 : m_libspdm_use_req_asym_algo;
419 :
420 1 : if (!libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
421 : m_libspdm_use_asym_algo, &data,
422 : &data_size, &hash, &hash_size)) {
423 0 : assert(false);
424 : }
425 1 : if (!libspdm_x509_get_cert_from_cert_chain(
426 1 : (uint8_t *)data + sizeof(spdm_cert_chain_t) + hash_size,
427 1 : data_size - sizeof(spdm_cert_chain_t) - hash_size, 0, &root_cert, &root_cert_size)) {
428 0 : assert(false);
429 : }
430 :
431 1 : spdm_context->local_context.peer_root_cert_provision_size[0] = root_cert_size;
432 1 : spdm_context->local_context.peer_root_cert_provision[0] = root_cert;
433 :
434 1 : libspdm_read_responder_public_certificate_chain(
435 : m_libspdm_use_hash_algo, m_libspdm_use_asym_algo,
436 : &m_libspdm_local_certificate_chain,
437 : &m_libspdm_local_certificate_chain_size, NULL, NULL);
438 :
439 1 : portion_length = LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN;
440 1 : remainder_length =
441 1 : (uint16_t)(m_libspdm_local_certificate_chain_size -
442 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN);
443 :
444 1 : temp_buf_size =
445 1 : sizeof(spdm_certificate_response_t) + portion_length;
446 1 : spdm_response_size = temp_buf_size;
447 1 : spdm_response = (void *)temp_buf;
448 :
449 1 : spdm_response->header.spdm_version = SPDM_MESSAGE_VERSION_13;
450 1 : spdm_response->header.request_response_code = SPDM_CERTIFICATE;
451 1 : spdm_response->header.param1 = 0;
452 1 : spdm_response->header.param2 = 0;
453 1 : spdm_response->portion_length = portion_length;
454 1 : spdm_response->remainder_length = remainder_length;
455 1 : libspdm_copy_mem(spdm_response + 1,
456 : sizeof(temp_buf) - sizeof(*spdm_response),
457 : (uint8_t *)m_libspdm_local_certificate_chain,
458 : portion_length);
459 :
460 : /* Sub Case 1: CertModel Value of 1 , DeviceCert model*/
461 1 : spdm_context->connection_info.multi_key_conn_req = true;
462 1 : spdm_context->encap_context.req_slot_id = 0;
463 1 : spdm_context->connection_info.peer_cert_info[0] = 0;
464 1 : spdm_context->mut_auth_cert_chain_buffer_size = 0;
465 1 : spdm_response->header.param2 = SPDM_CERTIFICATE_INFO_CERT_MODEL_DEVICE_CERT;
466 1 : libspdm_reset_message_mut_b(spdm_context);
467 :
468 1 : status = libspdm_process_encap_response_certificate(spdm_context, spdm_response_size,
469 : spdm_response,
470 : &need_continue);
471 :
472 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
473 1 : assert_int_equal(spdm_context->connection_info.peer_cert_info[0],
474 : SPDM_CERTIFICATE_INFO_CERT_MODEL_DEVICE_CERT);
475 1 : assert_int_equal(spdm_context->mut_auth_cert_chain_buffer_size,
476 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN);
477 1 : assert_memory_equal(spdm_context->mut_auth_cert_chain_buffer, m_libspdm_local_certificate_chain,
478 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN);
479 :
480 : /* Sub Case 2: CertModel Value of 2 , AliasCert model*/
481 1 : spdm_context->connection_info.multi_key_conn_req = true;
482 1 : spdm_context->encap_context.req_slot_id = 0;
483 1 : spdm_context->connection_info.peer_cert_info[0] = 0;
484 1 : spdm_response->header.param2 = SPDM_CERTIFICATE_INFO_CERT_MODEL_ALIAS_CERT;
485 1 : libspdm_reset_message_mut_b(spdm_context);
486 1 : libspdm_zero_mem(cert_chain, sizeof(cert_chain));
487 1 : spdm_context->mut_auth_cert_chain_buffer_size = 0;
488 1 : spdm_context->mut_auth_cert_chain_buffer = cert_chain;
489 :
490 1 : status = libspdm_process_encap_response_certificate(spdm_context, spdm_response_size,
491 : spdm_response,
492 : &need_continue);
493 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
494 1 : assert_int_equal(spdm_context->connection_info.peer_cert_info[0],
495 : SPDM_CERTIFICATE_INFO_CERT_MODEL_ALIAS_CERT);
496 1 : assert_int_equal(spdm_context->mut_auth_cert_chain_buffer_size,
497 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN);
498 1 : assert_memory_equal(spdm_context->mut_auth_cert_chain_buffer, m_libspdm_local_certificate_chain,
499 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN);
500 :
501 : /* Sub Case 3: CertModel Value of 3 GenericCert model , slot_id set 1
502 : * In all cases, the certificate model for slot 0 shall be either the device certificate model or the alias certificate model*/
503 1 : spdm_context->connection_info.multi_key_conn_req = true;
504 1 : spdm_context->encap_context.req_slot_id = 1;
505 1 : spdm_context->connection_info.peer_cert_info[1] = 0;
506 1 : spdm_context->mut_auth_cert_chain_buffer_size = 0;
507 1 : spdm_response->header.param1 = 1;
508 1 : spdm_response->header.param2 = SPDM_CERTIFICATE_INFO_CERT_MODEL_GENERIC_CERT;
509 1 : libspdm_reset_message_mut_b(spdm_context);
510 1 : libspdm_zero_mem(cert_chain, sizeof(cert_chain));
511 1 : spdm_context->mut_auth_cert_chain_buffer_size = 0;
512 1 : spdm_context->mut_auth_cert_chain_buffer = cert_chain;
513 :
514 1 : status = libspdm_process_encap_response_certificate(spdm_context, spdm_response_size,
515 : spdm_response,
516 : &need_continue);
517 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
518 1 : assert_int_equal(spdm_context->connection_info.peer_cert_info[1],
519 : SPDM_CERTIFICATE_INFO_CERT_MODEL_GENERIC_CERT);
520 1 : assert_int_equal(spdm_context->mut_auth_cert_chain_buffer_size,
521 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN);
522 1 : assert_memory_equal(spdm_context->mut_auth_cert_chain_buffer, m_libspdm_local_certificate_chain,
523 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN);
524 :
525 : /* Sub Case 4: CertModel Value of 3 , GenericCert model ,slot_id set 0
526 : * In all cases, the certificate model for slot 0 shall be either the device certificate model or the alias certificate model*/
527 1 : spdm_context->connection_info.multi_key_conn_req = true;
528 1 : spdm_context->encap_context.req_slot_id = 0;
529 1 : spdm_context->connection_info.peer_cert_info[0] = 0;
530 1 : spdm_context->mut_auth_cert_chain_buffer_size = 0;
531 1 : spdm_response->header.param1 = 0;
532 1 : spdm_response->header.param2 = SPDM_CERTIFICATE_INFO_CERT_MODEL_GENERIC_CERT;
533 1 : libspdm_reset_message_mut_b(spdm_context);
534 1 : libspdm_zero_mem(cert_chain, sizeof(cert_chain));
535 1 : spdm_context->mut_auth_cert_chain_buffer_size = 0;
536 1 : spdm_context->mut_auth_cert_chain_buffer = cert_chain;
537 :
538 1 : status = libspdm_process_encap_response_certificate(spdm_context, spdm_response_size,
539 : spdm_response,
540 : &need_continue);
541 1 : assert_int_equal(status, LIBSPDM_STATUS_INVALID_MSG_FIELD);
542 1 : assert_int_equal(spdm_context->connection_info.peer_cert_info[0], 0);
543 :
544 : /* Sub Case 5: CertModel Value of 0 , MULTI_KEY_CONN_REQ is true*/
545 : /* Value of 0 indicates either that the certificate slot does not contain any certificates or that the corresponding
546 : * MULTI_KEY_CONN_REQ or MULTI_KEY_CONN_RSP is false. */
547 1 : spdm_context->connection_info.multi_key_conn_req = true;
548 1 : spdm_context->encap_context.req_slot_id = 0;
549 1 : spdm_context->connection_info.peer_cert_info[0] = 0;
550 1 : spdm_context->mut_auth_cert_chain_buffer_size = 0;
551 1 : spdm_response->header.param2 = SPDM_CERTIFICATE_INFO_CERT_MODEL_NONE;
552 1 : libspdm_reset_message_mut_b(spdm_context);
553 1 : libspdm_zero_mem(cert_chain, sizeof(cert_chain));
554 1 : spdm_context->mut_auth_cert_chain_buffer_size = 0;
555 1 : spdm_context->mut_auth_cert_chain_buffer = cert_chain;
556 :
557 1 : status = libspdm_process_encap_response_certificate(spdm_context, spdm_response_size,
558 : spdm_response,
559 : &need_continue);
560 1 : assert_int_equal(status, LIBSPDM_STATUS_INVALID_MSG_FIELD);
561 1 : assert_int_equal(spdm_context->connection_info.peer_cert_info[0],
562 : SPDM_CERTIFICATE_INFO_CERT_MODEL_NONE);
563 :
564 : /* Sub Case 6: CertModel Value of 0 , MULTI_KEY_CONN_REQ is false*/
565 : /* Value of 0 indicates either that the certificate slot does not contain any certificates or that the corresponding
566 : * MULTI_KEY_CONN_REQ or MULTI_KEY_CONN_RSP is false. */
567 1 : spdm_context->connection_info.multi_key_conn_req = false;
568 1 : spdm_context->encap_context.req_slot_id = 0;
569 1 : spdm_context->connection_info.peer_cert_info[0] = 0;
570 1 : spdm_context->mut_auth_cert_chain_buffer_size = 0;
571 1 : spdm_response->header.param2 = SPDM_CERTIFICATE_INFO_CERT_MODEL_NONE;
572 1 : libspdm_reset_message_mut_b(spdm_context);
573 1 : libspdm_zero_mem(cert_chain, sizeof(cert_chain));
574 1 : spdm_context->mut_auth_cert_chain_buffer_size = 0;
575 1 : spdm_context->mut_auth_cert_chain_buffer = cert_chain;
576 :
577 1 : status = libspdm_process_encap_response_certificate(spdm_context, spdm_response_size,
578 : spdm_response,
579 : &need_continue);
580 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
581 1 : assert_int_equal(spdm_context->connection_info.peer_cert_info[0],
582 : SPDM_CERTIFICATE_INFO_CERT_MODEL_NONE);
583 1 : assert_int_equal(spdm_context->mut_auth_cert_chain_buffer_size,
584 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN);
585 1 : assert_memory_equal(spdm_context->mut_auth_cert_chain_buffer, m_libspdm_local_certificate_chain,
586 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN);
587 :
588 1 : free(data);
589 1 : free(m_libspdm_local_certificate_chain);
590 1 : m_libspdm_local_certificate_chain = NULL;
591 1 : m_libspdm_local_certificate_chain_size = 0;
592 1 : }
593 :
594 1 : int spdm_responder_encap_get_certificate_test_main(void)
595 : {
596 1 : const struct CMUnitTest spdm_responder_certificate_tests[] = {
597 : /* Success Case*/
598 : cmocka_unit_test(test_spdm_responder_encap_get_certificate_case1),
599 : /* Bad request size ,remaining length is 0*/
600 : cmocka_unit_test(test_spdm_responder_encap_get_certificate_case2),
601 : /* Error response: SPDM_ERROR_CODE_INVALID_REQUEST*/
602 : cmocka_unit_test(test_spdm_responder_encap_get_certificate_case2),
603 : /* Fail response: spdm_request.offset + spdm_response.portion_length + spdm_response.remainder_length !=
604 : * total_responder_cert_chain_buffer_length.*/
605 : cmocka_unit_test(test_spdm_responder_encap_get_certificate_case3),
606 : /* Fail response: responder return portion_length > spdm_request.length*/
607 : cmocka_unit_test(test_spdm_responder_encap_get_certificate_case4),
608 : /* check request attributes and response attributes*/
609 : cmocka_unit_test(test_spdm_responder_encap_get_certificate_case5),
610 : };
611 :
612 1 : libspdm_test_context_t test_context = {
613 : LIBSPDM_TEST_CONTEXT_VERSION,
614 : false,
615 : };
616 :
617 1 : libspdm_setup_test_context(&test_context);
618 :
619 1 : return cmocka_run_group_tests(spdm_responder_certificate_tests,
620 : libspdm_unit_test_group_setup,
621 : libspdm_unit_test_group_teardown);
622 : }
623 :
624 : #endif /* (LIBSPDM_ENABLE_CAPABILITY_MUT_AUTH_CAP) && (...) */
|