Line data Source code
1 : /**
2 : * Copyright Notice:
3 : * Copyright 2024-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 :
7 : #include <stdarg.h>
8 : #include <stddef.h>
9 : #include <setjmp.h>
10 : #include <stdint.h>
11 : #include <stdlib.h>
12 : #include <stdio.h>
13 : #include <assert.h>
14 : #include <string.h>
15 :
16 : #include <base.h>
17 : #include "library/memlib.h"
18 : #include "spdm_device_secret_lib_internal.h"
19 : #include "internal/libspdm_common_lib.h"
20 :
21 0 : bool libspdm_read_responder_root_public_certificate_by_size(
22 : uint32_t base_hash_algo, uint32_t base_asym_algo, uint16_t chain_id,
23 : void **data, size_t *size, void **hash, size_t *hash_size)
24 : {
25 : bool res;
26 : void *file_data;
27 : size_t file_size;
28 : spdm_cert_chain_t *cert_chain;
29 : size_t cert_chain_size;
30 : char *file;
31 : size_t digest_size;
32 :
33 0 : *data = NULL;
34 0 : *size = 0;
35 0 : if (hash != NULL) {
36 0 : *hash = NULL;
37 : }
38 0 : if (hash_size != NULL) {
39 0 : *hash_size = 0;
40 : }
41 :
42 0 : switch (chain_id) {
43 0 : case LIBSPDM_TEST_CERT_SMALL:
44 0 : file = "long_chains/Shorter1024B_ca.cert.der";
45 0 : break;
46 0 : case LIBSPDM_TEST_CERT_MAXINT16: /* data_size slightly smaller than 0x7FFF*/
47 0 : file = "long_chains/ShorterMAXINT16_ca.cert.der";
48 0 : break;
49 0 : case LIBSPDM_TEST_CERT_MAXUINT16: /* data_size slightly smaller than 0xFFFF*/
50 0 : file = "long_chains/ShorterMAXUINT16_ca.cert.der";
51 0 : break;
52 0 : case LIBSPDM_LIBSPDM_TEST_CERT_MAXUINT16_LARGER: /* data_size larger than 0xFFFF*/
53 0 : file = "long_chains/LongerMAXUINT16_ca.cert.der";
54 0 : break;
55 0 : default:
56 0 : LIBSPDM_ASSERT(false);
57 0 : return false;
58 : }
59 0 : res = libspdm_read_input_file(file, &file_data, &file_size);
60 0 : if (!res) {
61 0 : return res;
62 : }
63 :
64 0 : digest_size = libspdm_get_hash_size(base_hash_algo);
65 :
66 0 : cert_chain_size = sizeof(spdm_cert_chain_t) + digest_size + file_size;
67 0 : cert_chain = (void *)malloc(cert_chain_size);
68 0 : if (cert_chain == NULL) {
69 0 : free(file_data);
70 0 : return false;
71 : }
72 0 : cert_chain->length = (uint32_t)cert_chain_size;
73 :
74 0 : res = libspdm_hash_all(base_hash_algo, file_data, file_size,
75 0 : (uint8_t *)(cert_chain + 1));
76 0 : if (!res) {
77 0 : free(file_data);
78 0 : free(cert_chain);
79 0 : return res;
80 : }
81 0 : libspdm_copy_mem((uint8_t *)cert_chain + sizeof(spdm_cert_chain_t) + digest_size,
82 0 : cert_chain_size - (sizeof(spdm_cert_chain_t) + digest_size),
83 : file_data, file_size);
84 :
85 0 : *data = cert_chain;
86 0 : *size = cert_chain_size;
87 0 : if (hash != NULL) {
88 0 : *hash = (cert_chain + 1);
89 : }
90 0 : if (hash_size != NULL) {
91 0 : *hash_size = digest_size;
92 : }
93 :
94 0 : free(file_data);
95 0 : return true;
96 : }
97 :
98 8 : bool libspdm_read_responder_public_certificate_chain_by_size(
99 : uint32_t base_hash_algo, uint32_t base_asym_algo, uint16_t chain_id,
100 : void **data, size_t *size, void **hash, size_t *hash_size)
101 : {
102 : bool res;
103 : void *file_data;
104 : size_t file_size;
105 : spdm_cert_chain_t *cert_chain;
106 : size_t cert_chain_size;
107 : char *file;
108 : const uint8_t *root_cert;
109 : size_t root_cert_len;
110 : size_t digest_size;
111 : bool is_requester_cert;
112 : bool is_device_cert_model;
113 :
114 8 : is_requester_cert = false;
115 :
116 : /*default is true*/
117 8 : is_device_cert_model = true;
118 :
119 8 : *data = NULL;
120 8 : *size = 0;
121 8 : if (hash != NULL) {
122 2 : *hash = NULL;
123 : }
124 8 : if (hash_size != NULL) {
125 2 : *hash_size = 0;
126 : }
127 :
128 8 : switch (chain_id) {
129 3 : case LIBSPDM_TEST_CERT_SMALL: /* data_size smaller than 1024 Bytes*/
130 3 : file = "long_chains/Shorter1024B_bundle_responder.certchain.der";
131 3 : break;
132 2 : case LIBSPDM_TEST_CERT_MAXINT16: /* data_size slightly smaller than 0x7FFF*/
133 2 : file = "long_chains/ShorterMAXINT16_bundle_responder.certchain.der";
134 2 : break;
135 3 : case LIBSPDM_TEST_CERT_MAXUINT16: /* data_size slightly smaller than 0xFFFF*/
136 3 : file = "long_chains/ShorterMAXUINT16_bundle_responder.certchain.der";
137 3 : break;
138 0 : case LIBSPDM_LIBSPDM_TEST_CERT_MAXUINT16_LARGER: /* data_size larger than 0xFFFF*/
139 0 : file = "long_chains/LongerMAXUINT16_bundle_responder.certchain.der";
140 0 : break;
141 0 : default:
142 0 : LIBSPDM_ASSERT(false);
143 0 : return false;
144 : }
145 8 : res = libspdm_read_input_file(file, &file_data, &file_size);
146 8 : if (!res) {
147 0 : return res;
148 : }
149 :
150 8 : digest_size = libspdm_get_hash_size(base_hash_algo);
151 :
152 8 : cert_chain_size = sizeof(spdm_cert_chain_t) + digest_size + file_size;
153 8 : cert_chain = (void *)malloc(cert_chain_size);
154 8 : if (cert_chain == NULL) {
155 0 : free(file_data);
156 0 : return false;
157 : }
158 8 : cert_chain->length = (uint32_t)cert_chain_size;
159 :
160 8 : res = libspdm_verify_cert_chain_data(file_data, file_size,
161 : base_asym_algo, base_hash_algo,
162 : is_requester_cert, is_device_cert_model);
163 8 : if (!res) {
164 0 : free(file_data);
165 0 : free(cert_chain);
166 0 : return res;
167 : }
168 :
169 :
170 : /* Get Root Certificate and calculate hash value*/
171 :
172 8 : res = libspdm_x509_get_cert_from_cert_chain(file_data, file_size, 0, &root_cert,
173 : &root_cert_len);
174 8 : if (!res) {
175 0 : free(file_data);
176 0 : free(cert_chain);
177 0 : return res;
178 : }
179 :
180 8 : res = libspdm_hash_all(base_hash_algo, root_cert, root_cert_len,
181 8 : (uint8_t *)(cert_chain + 1));
182 8 : if (!res) {
183 0 : free(file_data);
184 0 : free(cert_chain);
185 0 : return res;
186 : }
187 8 : libspdm_copy_mem((uint8_t *)cert_chain + sizeof(spdm_cert_chain_t) + digest_size,
188 8 : cert_chain_size - (sizeof(spdm_cert_chain_t) + digest_size),
189 : file_data, file_size);
190 :
191 8 : *data = cert_chain;
192 8 : *size = cert_chain_size;
193 8 : if (hash != NULL) {
194 2 : *hash = (cert_chain + 1);
195 : }
196 8 : if (hash_size != NULL) {
197 2 : *hash_size = digest_size;
198 : }
199 :
200 8 : free(file_data);
201 8 : return true;
202 : }
|