Line data Source code
1 : /**
2 : * Copyright Notice:
3 : * Copyright 2024 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 = (uint16_t)cert_chain_size;
73 0 : cert_chain->reserved = 0;
74 :
75 0 : res = libspdm_hash_all(base_hash_algo, file_data, file_size,
76 0 : (uint8_t *)(cert_chain + 1));
77 0 : if (!res) {
78 0 : free(file_data);
79 0 : free(cert_chain);
80 0 : return res;
81 : }
82 0 : libspdm_copy_mem((uint8_t *)cert_chain + sizeof(spdm_cert_chain_t) + digest_size,
83 0 : cert_chain_size - (sizeof(spdm_cert_chain_t) + digest_size),
84 : file_data, file_size);
85 :
86 0 : *data = cert_chain;
87 0 : *size = cert_chain_size;
88 0 : if (hash != NULL) {
89 0 : *hash = (cert_chain + 1);
90 : }
91 0 : if (hash_size != NULL) {
92 0 : *hash_size = digest_size;
93 : }
94 :
95 0 : free(file_data);
96 0 : return true;
97 : }
98 :
99 8 : bool libspdm_read_responder_public_certificate_chain_by_size(
100 : uint32_t base_hash_algo, uint32_t base_asym_algo, uint16_t chain_id,
101 : void **data, size_t *size, void **hash, size_t *hash_size)
102 : {
103 : bool res;
104 : void *file_data;
105 : size_t file_size;
106 : spdm_cert_chain_t *cert_chain;
107 : size_t cert_chain_size;
108 : char *file;
109 : const uint8_t *root_cert;
110 : size_t root_cert_len;
111 : size_t digest_size;
112 : bool is_requester_cert;
113 : bool is_device_cert_model;
114 :
115 8 : is_requester_cert = false;
116 :
117 : /*default is true*/
118 8 : is_device_cert_model = true;
119 :
120 8 : *data = NULL;
121 8 : *size = 0;
122 8 : if (hash != NULL) {
123 2 : *hash = NULL;
124 : }
125 8 : if (hash_size != NULL) {
126 2 : *hash_size = 0;
127 : }
128 :
129 8 : switch (chain_id) {
130 3 : case LIBSPDM_TEST_CERT_SMALL: /* data_size smaller than 1024 Bytes*/
131 3 : file = "long_chains/Shorter1024B_bundle_responder.certchain.der";
132 3 : break;
133 2 : case LIBSPDM_TEST_CERT_MAXINT16: /* data_size slightly smaller than 0x7FFF*/
134 2 : file = "long_chains/ShorterMAXINT16_bundle_responder.certchain.der";
135 2 : break;
136 3 : case LIBSPDM_TEST_CERT_MAXUINT16: /* data_size slightly smaller than 0xFFFF*/
137 3 : file = "long_chains/ShorterMAXUINT16_bundle_responder.certchain.der";
138 3 : break;
139 0 : case LIBSPDM_LIBSPDM_TEST_CERT_MAXUINT16_LARGER: /* data_size larger than 0xFFFF*/
140 0 : file = "long_chains/LongerMAXUINT16_bundle_responder.certchain.der";
141 0 : break;
142 0 : default:
143 0 : LIBSPDM_ASSERT(false);
144 0 : return false;
145 : }
146 8 : res = libspdm_read_input_file(file, &file_data, &file_size);
147 8 : if (!res) {
148 0 : return res;
149 : }
150 :
151 8 : digest_size = libspdm_get_hash_size(base_hash_algo);
152 :
153 8 : cert_chain_size = sizeof(spdm_cert_chain_t) + digest_size + file_size;
154 8 : cert_chain = (void *)malloc(cert_chain_size);
155 8 : if (cert_chain == NULL) {
156 0 : free(file_data);
157 0 : return false;
158 : }
159 8 : cert_chain->length = (uint16_t)cert_chain_size;
160 8 : cert_chain->reserved = 0;
161 :
162 8 : res = libspdm_verify_cert_chain_data(file_data, file_size,
163 : base_asym_algo, base_hash_algo,
164 : is_requester_cert, is_device_cert_model);
165 8 : if (!res) {
166 0 : free(file_data);
167 0 : free(cert_chain);
168 0 : return res;
169 : }
170 :
171 :
172 : /* Get Root Certificate and calculate hash value*/
173 :
174 8 : res = libspdm_x509_get_cert_from_cert_chain(file_data, file_size, 0, &root_cert,
175 : &root_cert_len);
176 8 : if (!res) {
177 0 : free(file_data);
178 0 : free(cert_chain);
179 0 : return res;
180 : }
181 :
182 8 : res = libspdm_hash_all(base_hash_algo, root_cert, root_cert_len,
183 8 : (uint8_t *)(cert_chain + 1));
184 8 : if (!res) {
185 0 : free(file_data);
186 0 : free(cert_chain);
187 0 : return res;
188 : }
189 8 : libspdm_copy_mem((uint8_t *)cert_chain + sizeof(spdm_cert_chain_t) + digest_size,
190 8 : cert_chain_size - (sizeof(spdm_cert_chain_t) + digest_size),
191 : file_data, file_size);
192 :
193 8 : *data = cert_chain;
194 8 : *size = cert_chain_size;
195 8 : if (hash != NULL) {
196 2 : *hash = (cert_chain + 1);
197 : }
198 8 : if (hash_size != NULL) {
199 2 : *hash_size = digest_size;
200 : }
201 :
202 8 : free(file_data);
203 8 : return true;
204 : }
|