Line data Source code
1 : /**
2 : * Copyright Notice:
3 : * Copyright 2021-2022 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 : 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 1 : libspdm_x509_get_cert_from_cert_chain((uint8_t *)data + sizeof(spdm_cert_chain_t) + hash_size,
60 1 : data_size - sizeof(spdm_cert_chain_t) - hash_size, 0,
61 : &root_cert, &root_cert_size);
62 1 : libspdm_dump_hex(
63 : root_cert,
64 : root_cert_size);
65 1 : spdm_context->local_context.peer_root_cert_provision_size[0] =
66 : 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 =
70 : m_libspdm_use_hash_algo;
71 :
72 1 : spdm_context->connection_info.algorithm.req_base_asym_alg =
73 : SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P256;
74 :
75 1 : if (m_libspdm_local_certificate_chain == NULL) {
76 1 : libspdm_read_responder_public_certificate_chain(
77 : m_libspdm_use_hash_algo, m_libspdm_use_asym_algo,
78 : &m_libspdm_local_certificate_chain,
79 : &m_libspdm_local_certificate_chain_size, NULL, NULL);
80 : }
81 :
82 1 : portion_length = LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN;
83 1 : remainder_length =
84 1 : (uint16_t)(m_libspdm_local_certificate_chain_size -
85 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN *
86 1 : (calling_index + 1));
87 :
88 1 : temp_buf_size =
89 1 : 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 1 : }
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 : void test_spdm_responder_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 =
143 : LIBSPDM_CONNECTION_STATE_AFTER_DIGESTS;
144 2 : spdm_context->connection_info.capability.flags |=
145 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
146 2 : libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
147 : m_libspdm_use_asym_algo, &data,
148 : &data_size, &hash, &hash_size);
149 2 : libspdm_x509_get_cert_from_cert_chain((uint8_t *)data + sizeof(spdm_cert_chain_t) + hash_size,
150 2 : data_size - sizeof(spdm_cert_chain_t) - hash_size, 0,
151 : &root_cert, &root_cert_size);
152 2 : spdm_context->local_context.peer_root_cert_provision_size[0] =
153 : root_cert_size;
154 2 : spdm_context->local_context.peer_root_cert_provision[0] = root_cert;
155 2 : libspdm_reset_message_b(spdm_context);
156 2 : spdm_context->connection_info.algorithm.base_hash_algo =
157 : 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 : void test_spdm_responder_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 |=
207 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
208 1 : libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
209 : m_libspdm_use_asym_algo, &data,
210 : &data_size, &hash, &hash_size);
211 1 : libspdm_x509_get_cert_from_cert_chain((uint8_t *)data + sizeof(spdm_cert_chain_t) + hash_size,
212 1 : data_size - sizeof(spdm_cert_chain_t) - hash_size, 0,
213 : &root_cert, &root_cert_size);
214 1 : libspdm_dump_hex(
215 : root_cert,
216 : root_cert_size);
217 1 : spdm_context->local_context.peer_root_cert_provision_size[0] =
218 : 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 =
222 : m_libspdm_use_hash_algo;
223 :
224 :
225 1 : spdm_context->connection_info.algorithm.req_base_asym_alg =
226 : SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P256;
227 :
228 1 : if (m_libspdm_local_certificate_chain == NULL) {
229 1 : libspdm_read_responder_public_certificate_chain(
230 : m_libspdm_use_hash_algo, m_libspdm_use_asym_algo,
231 : &m_libspdm_local_certificate_chain,
232 : &m_libspdm_local_certificate_chain_size, NULL, NULL);
233 : }
234 :
235 1 : portion_length = 0;
236 : /* Fail response: spdm_request.offset + spdm_response.portion_length + spdm_response.remainder_length !=
237 : * total_responder_cert_chain_buffer_length.*/
238 1 : remainder_length =
239 1 : (uint16_t)(m_libspdm_local_certificate_chain_size - 1 -
240 1 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN * (calling_index + 1));
241 :
242 1 : temp_buf_size =
243 1 : 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 1 : }
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 : void test_spdm_responder_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 :
296 1 : spdm_test_context = *state;
297 1 : spdm_context = spdm_test_context->spdm_context;
298 1 : spdm_test_context->case_id = 0x4;
299 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_10 <<
300 : SPDM_VERSION_NUMBER_SHIFT_BIT;
301 1 : spdm_context->connection_info.capability.flags |=
302 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
303 1 : libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
304 : m_libspdm_use_asym_algo, &data,
305 : &data_size, &hash, &hash_size);
306 1 : libspdm_x509_get_cert_from_cert_chain((uint8_t *)data + sizeof(spdm_cert_chain_t) + hash_size,
307 1 : data_size - sizeof(spdm_cert_chain_t) - hash_size, 0,
308 : &root_cert, &root_cert_size);
309 1 : libspdm_dump_hex(
310 : root_cert,
311 : root_cert_size);
312 1 : spdm_context->local_context.peer_root_cert_provision_size[0] =
313 : root_cert_size;
314 1 : spdm_context->local_context.peer_root_cert_provision[0] = root_cert;
315 1 : libspdm_reset_message_b(spdm_context);
316 1 : spdm_context->connection_info.algorithm.base_hash_algo =
317 : m_libspdm_use_hash_algo;
318 :
319 1 : spdm_context->connection_info.algorithm.req_base_asym_alg =
320 : SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P256;
321 :
322 1 : if (m_libspdm_local_certificate_chain == NULL) {
323 1 : libspdm_read_responder_public_certificate_chain(
324 : m_libspdm_use_hash_algo, m_libspdm_use_asym_algo,
325 : &m_libspdm_local_certificate_chain,
326 : &m_libspdm_local_certificate_chain_size, NULL, NULL);
327 : }
328 :
329 1 : portion_length = LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN + 1; /* Fail response: responder return portion_length > spdm_request.length*/
330 1 : remainder_length =
331 1 : (uint16_t)(m_libspdm_local_certificate_chain_size - 1 -
332 1 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN * (calling_index + 1));
333 :
334 1 : temp_buf_size =
335 1 : sizeof(spdm_certificate_response_t) + portion_length;
336 1 : spdm_response_size = temp_buf_size;
337 1 : spdm_response = (void *)temp_buf;
338 :
339 1 : spdm_response->header.spdm_version = SPDM_MESSAGE_VERSION_10;
340 1 : spdm_response->header.request_response_code = SPDM_CERTIFICATE;
341 1 : spdm_response->header.param1 = 0;
342 1 : spdm_response->header.param2 = 0;
343 1 : spdm_response->portion_length = portion_length;
344 1 : spdm_response->remainder_length = remainder_length;
345 1 : libspdm_copy_mem(spdm_response + 1,
346 : sizeof(temp_buf) - sizeof(*spdm_response),
347 1 : (uint8_t *)m_libspdm_local_certificate_chain +
348 1 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN * calling_index,
349 : portion_length);
350 :
351 1 : free(m_libspdm_local_certificate_chain);
352 1 : m_libspdm_local_certificate_chain = NULL;
353 1 : m_libspdm_local_certificate_chain_size = 0;
354 :
355 1 : status = libspdm_process_encap_response_certificate(spdm_context, spdm_response_size,
356 : spdm_response,
357 : &need_continue);
358 1 : assert_int_equal(status, LIBSPDM_STATUS_INVALID_MSG_FIELD);
359 :
360 1 : spdm_context->mut_auth_cert_chain_buffer_size = 0;
361 1 : free(data);
362 1 : }
363 :
364 : /**
365 : * Test 5: check request attributes and response attributes ,
366 : * Set CertModel to determine whether it meets expectations
367 : * Expected Behavior: requester returns the status LIBSPDM_STATUS_SUCCESS
368 : * Expected Behavior: CertModel is GenericCert model and slot 0 , returns a status of RETURN_DEVICE_ERROR.
369 : * Expected Behavior: CertModel Value of 0 and certificate chain is valid, returns a status of RETURN_DEVICE_ERROR.
370 : **/
371 1 : void test_spdm_responder_encap_get_certificate_case5(void **state)
372 : {
373 : libspdm_return_t status;
374 : libspdm_test_context_t *spdm_test_context;
375 : libspdm_context_t *spdm_context;
376 : void *data;
377 : size_t data_size;
378 : void *hash;
379 : size_t hash_size;
380 : const uint8_t *root_cert;
381 : size_t root_cert_size;
382 : bool need_continue;
383 : spdm_certificate_response_t *spdm_response;
384 : uint8_t temp_buf[LIBSPDM_MAX_SPDM_MSG_SIZE];
385 : size_t temp_buf_size;
386 : uint8_t cert_chain[LIBSPDM_MAX_CERT_CHAIN_SIZE];
387 : uint16_t portion_length;
388 : uint16_t remainder_length;
389 : size_t spdm_response_size;
390 :
391 1 : spdm_test_context = *state;
392 1 : spdm_context = spdm_test_context->spdm_context;
393 1 : spdm_test_context->case_id = 0x5;
394 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_13 <<
395 : SPDM_VERSION_NUMBER_SHIFT_BIT;
396 1 : spdm_context->connection_info.capability.flags = 0;
397 1 : spdm_context->connection_info.capability.flags |=
398 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
399 1 : spdm_context->connection_info.algorithm.base_hash_algo =
400 : m_libspdm_use_hash_algo;
401 1 : spdm_context->connection_info.algorithm.req_base_asym_alg =
402 : m_libspdm_use_req_asym_algo;
403 :
404 1 : libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
405 : m_libspdm_use_asym_algo, &data,
406 : &data_size, &hash, &hash_size);
407 1 : libspdm_x509_get_cert_from_cert_chain((uint8_t *)data + sizeof(spdm_cert_chain_t) + hash_size,
408 1 : data_size - sizeof(spdm_cert_chain_t) - hash_size, 0,
409 : &root_cert, &root_cert_size);
410 :
411 1 : spdm_context->local_context.peer_root_cert_provision_size[0] = root_cert_size;
412 1 : spdm_context->local_context.peer_root_cert_provision[0] = root_cert;
413 :
414 1 : libspdm_read_responder_public_certificate_chain(
415 : m_libspdm_use_hash_algo, m_libspdm_use_asym_algo,
416 : &m_libspdm_local_certificate_chain,
417 : &m_libspdm_local_certificate_chain_size, NULL, NULL);
418 :
419 1 : portion_length = LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN;
420 1 : remainder_length =
421 1 : (uint16_t)(m_libspdm_local_certificate_chain_size -
422 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN);
423 :
424 1 : temp_buf_size =
425 1 : sizeof(spdm_certificate_response_t) + portion_length;
426 1 : spdm_response_size = temp_buf_size;
427 1 : spdm_response = (void *)temp_buf;
428 :
429 1 : spdm_response->header.spdm_version = SPDM_MESSAGE_VERSION_13;
430 1 : spdm_response->header.request_response_code = SPDM_CERTIFICATE;
431 1 : spdm_response->header.param1 = 0;
432 1 : spdm_response->header.param2 = 0;
433 1 : spdm_response->portion_length = portion_length;
434 1 : spdm_response->remainder_length = remainder_length;
435 1 : libspdm_copy_mem(spdm_response + 1,
436 : sizeof(temp_buf) - sizeof(*spdm_response),
437 : (uint8_t *)m_libspdm_local_certificate_chain,
438 : portion_length);
439 :
440 : /* Sub Case 1: CertModel Value of 1 , DeviceCert model*/
441 1 : spdm_context->connection_info.multi_key_conn_req = true;
442 1 : spdm_context->encap_context.req_slot_id = 0;
443 1 : spdm_context->connection_info.peer_cert_info[0] = 0;
444 1 : spdm_context->mut_auth_cert_chain_buffer_size = 0;
445 1 : spdm_response->header.param2 = SPDM_CERTIFICATE_INFO_CERT_MODEL_DEVICE_CERT;
446 1 : libspdm_reset_message_mut_b(spdm_context);
447 :
448 1 : status = libspdm_process_encap_response_certificate(spdm_context, spdm_response_size,
449 : spdm_response,
450 : &need_continue);
451 :
452 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
453 1 : assert_int_equal(spdm_context->connection_info.peer_cert_info[0],
454 : SPDM_CERTIFICATE_INFO_CERT_MODEL_DEVICE_CERT);
455 1 : assert_int_equal(spdm_context->mut_auth_cert_chain_buffer_size,
456 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN);
457 1 : assert_memory_equal(spdm_context->mut_auth_cert_chain_buffer, m_libspdm_local_certificate_chain,
458 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN);
459 :
460 : /* Sub Case 2: CertModel Value of 2 , AliasCert 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_response->header.param2 = SPDM_CERTIFICATE_INFO_CERT_MODEL_ALIAS_CERT;
465 1 : libspdm_reset_message_mut_b(spdm_context);
466 1 : libspdm_zero_mem(cert_chain, sizeof(cert_chain));
467 1 : spdm_context->mut_auth_cert_chain_buffer_size = 0;
468 1 : spdm_context->mut_auth_cert_chain_buffer = cert_chain;
469 :
470 1 : status = libspdm_process_encap_response_certificate(spdm_context, spdm_response_size,
471 : spdm_response,
472 : &need_continue);
473 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
474 1 : assert_int_equal(spdm_context->connection_info.peer_cert_info[0],
475 : SPDM_CERTIFICATE_INFO_CERT_MODEL_ALIAS_CERT);
476 1 : assert_int_equal(spdm_context->mut_auth_cert_chain_buffer_size,
477 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN);
478 1 : assert_memory_equal(spdm_context->mut_auth_cert_chain_buffer, m_libspdm_local_certificate_chain,
479 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN);
480 :
481 : /* Sub Case 3: CertModel Value of 3 GenericCert model , slot_id set 1
482 : * In all cases, the certificate model for slot 0 shall be either the device certificate model or the alias certificate model*/
483 1 : spdm_context->connection_info.multi_key_conn_req = true;
484 1 : spdm_context->encap_context.req_slot_id = 1;
485 1 : spdm_context->connection_info.peer_cert_info[1] = 0;
486 1 : spdm_context->mut_auth_cert_chain_buffer_size = 0;
487 1 : spdm_response->header.param1 = 1;
488 1 : spdm_response->header.param2 = SPDM_CERTIFICATE_INFO_CERT_MODEL_GENERIC_CERT;
489 1 : libspdm_reset_message_mut_b(spdm_context);
490 1 : libspdm_zero_mem(cert_chain, sizeof(cert_chain));
491 1 : spdm_context->mut_auth_cert_chain_buffer_size = 0;
492 1 : spdm_context->mut_auth_cert_chain_buffer = cert_chain;
493 :
494 1 : status = libspdm_process_encap_response_certificate(spdm_context, spdm_response_size,
495 : spdm_response,
496 : &need_continue);
497 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
498 1 : assert_int_equal(spdm_context->connection_info.peer_cert_info[1],
499 : SPDM_CERTIFICATE_INFO_CERT_MODEL_GENERIC_CERT);
500 1 : assert_int_equal(spdm_context->mut_auth_cert_chain_buffer_size,
501 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN);
502 1 : assert_memory_equal(spdm_context->mut_auth_cert_chain_buffer, m_libspdm_local_certificate_chain,
503 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN);
504 :
505 : /* Sub Case 4: CertModel Value of 3 , GenericCert model ,slot_id set 0
506 : * In all cases, the certificate model for slot 0 shall be either the device certificate model or the alias certificate model*/
507 1 : spdm_context->connection_info.multi_key_conn_req = true;
508 1 : spdm_context->encap_context.req_slot_id = 0;
509 1 : spdm_context->connection_info.peer_cert_info[0] = 0;
510 1 : spdm_context->mut_auth_cert_chain_buffer_size = 0;
511 1 : spdm_response->header.param1 = 0;
512 1 : spdm_response->header.param2 = SPDM_CERTIFICATE_INFO_CERT_MODEL_GENERIC_CERT;
513 1 : libspdm_reset_message_mut_b(spdm_context);
514 1 : libspdm_zero_mem(cert_chain, sizeof(cert_chain));
515 1 : spdm_context->mut_auth_cert_chain_buffer_size = 0;
516 1 : spdm_context->mut_auth_cert_chain_buffer = cert_chain;
517 :
518 1 : status = libspdm_process_encap_response_certificate(spdm_context, spdm_response_size,
519 : spdm_response,
520 : &need_continue);
521 1 : assert_int_equal(status, LIBSPDM_STATUS_INVALID_MSG_FIELD);
522 1 : assert_int_equal(spdm_context->connection_info.peer_cert_info[0], 0);
523 :
524 : /* Sub Case 5: CertModel Value of 0 , MULTI_KEY_CONN_REQ is true*/
525 : /* Value of 0 indicates either that the certificate slot does not contain any certificates or that the corresponding
526 : * MULTI_KEY_CONN_REQ or MULTI_KEY_CONN_RSP is false. */
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.param2 = SPDM_CERTIFICATE_INFO_CERT_MODEL_NONE;
532 1 : libspdm_reset_message_mut_b(spdm_context);
533 1 : libspdm_zero_mem(cert_chain, sizeof(cert_chain));
534 1 : spdm_context->mut_auth_cert_chain_buffer_size = 0;
535 1 : spdm_context->mut_auth_cert_chain_buffer = cert_chain;
536 :
537 1 : status = libspdm_process_encap_response_certificate(spdm_context, spdm_response_size,
538 : spdm_response,
539 : &need_continue);
540 1 : assert_int_equal(status, LIBSPDM_STATUS_INVALID_MSG_FIELD);
541 1 : assert_int_equal(spdm_context->connection_info.peer_cert_info[0],
542 : SPDM_CERTIFICATE_INFO_CERT_MODEL_NONE);
543 :
544 : /* Sub Case 6: CertModel Value of 0 , MULTI_KEY_CONN_REQ is false*/
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 = false;
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_SUCCESS);
561 1 : assert_int_equal(spdm_context->connection_info.peer_cert_info[0],
562 : SPDM_CERTIFICATE_INFO_CERT_MODEL_NONE);
563 1 : assert_int_equal(spdm_context->mut_auth_cert_chain_buffer_size,
564 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN);
565 1 : assert_memory_equal(spdm_context->mut_auth_cert_chain_buffer, m_libspdm_local_certificate_chain,
566 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN);
567 :
568 1 : free(data);
569 1 : free(m_libspdm_local_certificate_chain);
570 1 : m_libspdm_local_certificate_chain = NULL;
571 1 : m_libspdm_local_certificate_chain_size = 0;
572 1 : }
573 :
574 1 : int spdm_responder_encap_get_certificate_test_main(void)
575 : {
576 1 : const struct CMUnitTest spdm_responder_certificate_tests[] = {
577 : /* Success Case*/
578 : cmocka_unit_test(test_spdm_responder_encap_get_certificate_case1),
579 : /* Bad request size ,remaining length is 0*/
580 : cmocka_unit_test(test_spdm_responder_encap_get_certificate_case2),
581 : /* Error response: SPDM_ERROR_CODE_INVALID_REQUEST*/
582 : cmocka_unit_test(test_spdm_responder_encap_get_certificate_case2),
583 : /* Fail response: spdm_request.offset + spdm_response.portion_length + spdm_response.remainder_length !=
584 : * total_responder_cert_chain_buffer_length.*/
585 : cmocka_unit_test(test_spdm_responder_encap_get_certificate_case3),
586 : /* Fail response: responder return portion_length > spdm_request.length*/
587 : cmocka_unit_test(test_spdm_responder_encap_get_certificate_case4),
588 : /* check request attributes and response attributes*/
589 : cmocka_unit_test(test_spdm_responder_encap_get_certificate_case5),
590 : };
591 :
592 1 : libspdm_test_context_t test_context = {
593 : LIBSPDM_TEST_CONTEXT_VERSION,
594 : false,
595 : };
596 :
597 1 : libspdm_setup_test_context(&test_context);
598 :
599 1 : return cmocka_run_group_tests(spdm_responder_certificate_tests,
600 : libspdm_unit_test_group_setup,
601 : libspdm_unit_test_group_teardown);
602 : }
603 :
604 : #endif /* (LIBSPDM_ENABLE_CAPABILITY_MUT_AUTH_CAP) && (...) */
|