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