blob: d396abed497ccee34af9bf0cc3fc17f5f0e4df7f [file] [log] [blame]
Sampa Misrad823cc02020-03-24 04:53:20 -05001#include "file_io_type_cert.hpp"
2
Deepak Kodihallid130e1a2020-06-17 05:55:32 -05003#include "common/utils.hpp"
Sampa Misrad823cc02020-03-24 04:53:20 -05004
George Liuc453e162022-12-21 17:16:23 +08005#include <libpldm/base.h>
6#include <libpldm/file_io.h>
Sampa Misrad823cc02020-03-24 04:53:20 -05007#include <stdint.h>
8
9#include <iostream>
10
Sampa Misrad823cc02020-03-24 04:53:20 -050011namespace pldm
12{
Brad Bishop5079ac42021-08-19 18:35:06 -040013using namespace utils;
14
Sampa Misrad823cc02020-03-24 04:53:20 -050015namespace responder
16{
Sridevi Rameshe3b3f632022-06-14 05:28:15 -050017constexpr auto certObjPath = "/xyz/openbmc_project/certs/ca/entry/";
18constexpr auto certEntryIntf = "xyz.openbmc_project.Certs.Entry";
Varsha Kaverappa219ace92021-04-01 02:50:11 -050019static constexpr auto certFilePath = "/var/lib/ibm/bmcweb/";
Sampa Misrad823cc02020-03-24 04:53:20 -050020
21CertMap CertHandler::certMap;
22
23int CertHandler::writeFromMemory(uint32_t offset, uint32_t length,
Sampa Misra69508502020-09-08 00:08:21 -050024 uint64_t address,
25 oem_platform::Handler* /*oemPlatformHandler*/)
Sampa Misrad823cc02020-03-24 04:53:20 -050026{
27 auto it = certMap.find(certType);
28 if (it == certMap.end())
29 {
Sridevi Rameshe3b3f632022-06-14 05:28:15 -050030 std::cerr << "CertHandler::writeFromMemory:file for type " << certType
31 << " doesn't exist\n";
Sampa Misrad823cc02020-03-24 04:53:20 -050032 return PLDM_ERROR;
33 }
34
35 auto fd = std::get<0>(it->second);
36 auto& remSize = std::get<1>(it->second);
37 auto rc = transferFileData(fd, false, offset, length, address);
38 if (rc == PLDM_SUCCESS)
39 {
40 remSize -= length;
41 if (!remSize)
42 {
43 close(fd);
44 certMap.erase(it);
45 }
46 }
47 return rc;
48}
49
50int CertHandler::readIntoMemory(uint32_t offset, uint32_t& length,
Sampa Misra69508502020-09-08 00:08:21 -050051 uint64_t address,
52 oem_platform::Handler* /*oemPlatformHandler*/)
Sampa Misrad823cc02020-03-24 04:53:20 -050053{
Varsha Kaverappa219ace92021-04-01 02:50:11 -050054 std::string filePath = certFilePath;
55 filePath += "CSR_" + std::to_string(fileHandle);
Sampa Misrad823cc02020-03-24 04:53:20 -050056 if (certType != PLDM_FILE_TYPE_CERT_SIGNING_REQUEST)
57 {
58 return PLDM_ERROR_INVALID_DATA;
59 }
Varsha Kaverappa219ace92021-04-01 02:50:11 -050060 auto rc = transferFileData(filePath.c_str(), true, offset, length, address);
61 fs::remove(filePath);
62 if (rc)
63 {
64 return PLDM_ERROR;
65 }
66 return PLDM_SUCCESS;
Sampa Misrad823cc02020-03-24 04:53:20 -050067}
68
Sampa Misra69508502020-09-08 00:08:21 -050069int CertHandler::read(uint32_t offset, uint32_t& length, Response& response,
70 oem_platform::Handler* /*oemPlatformHandler*/)
Sampa Misrad823cc02020-03-24 04:53:20 -050071{
Sridevi Rameshe3b3f632022-06-14 05:28:15 -050072 std::cout
73 << "CertHandler::read:Read file response for Sign CSR, file handle: "
74 << fileHandle << std::endl;
Varsha Kaverappa219ace92021-04-01 02:50:11 -050075 std::string filePath = certFilePath;
76 filePath += "CSR_" + std::to_string(fileHandle);
Sampa Misrad823cc02020-03-24 04:53:20 -050077 if (certType != PLDM_FILE_TYPE_CERT_SIGNING_REQUEST)
78 {
79 return PLDM_ERROR_INVALID_DATA;
80 }
Varsha Kaverappa219ace92021-04-01 02:50:11 -050081 auto rc = readFile(filePath.c_str(), offset, length, response);
82 fs::remove(filePath);
83 if (rc)
84 {
85 return PLDM_ERROR;
86 }
87 return PLDM_SUCCESS;
Sampa Misrad823cc02020-03-24 04:53:20 -050088}
89
Sampa Misra69508502020-09-08 00:08:21 -050090int CertHandler::write(const char* buffer, uint32_t offset, uint32_t& length,
91 oem_platform::Handler* /*oemPlatformHandler*/)
Sampa Misrad823cc02020-03-24 04:53:20 -050092{
93 auto it = certMap.find(certType);
94 if (it == certMap.end())
95 {
Sridevi Rameshe3b3f632022-06-14 05:28:15 -050096 std::cerr << "CertHandler::write:file for type " << certType
97 << " doesn't exist\n";
Sampa Misrad823cc02020-03-24 04:53:20 -050098 return PLDM_ERROR;
99 }
100
101 auto fd = std::get<0>(it->second);
102 int rc = lseek(fd, offset, SEEK_SET);
103 if (rc == -1)
104 {
Sridevi Rameshe3b3f632022-06-14 05:28:15 -0500105 std::cerr << "CertHandler::write:lseek failed, ERROR=" << errno
106 << ", OFFSET=" << offset << "\n";
Sampa Misrad823cc02020-03-24 04:53:20 -0500107 return PLDM_ERROR;
108 }
109 rc = ::write(fd, buffer, length);
110 if (rc == -1)
111 {
Sridevi Rameshe3b3f632022-06-14 05:28:15 -0500112 std::cerr << "CertHandler::write:file write failed, ERROR=" << errno
Sampa Misrad823cc02020-03-24 04:53:20 -0500113 << ", LENGTH=" << length << ", OFFSET=" << offset << "\n";
114 return PLDM_ERROR;
115 }
116 length = rc;
117 auto& remSize = std::get<1>(it->second);
118 remSize -= length;
119 if (!remSize)
120 {
121 close(fd);
122 certMap.erase(it);
123 }
Varsha Kaverappa219ace92021-04-01 02:50:11 -0500124
125 if (certType == PLDM_FILE_TYPE_SIGNED_CERT)
126 {
127 constexpr auto certObjPath = "/xyz/openbmc_project/certs/ca/entry/";
128 constexpr auto certEntryIntf = "xyz.openbmc_project.Certs.Entry";
129
130 std::string filePath = certFilePath;
131 filePath += "ClientCert_" + std::to_string(fileHandle);
132
133 std::ifstream inFile;
134 inFile.open(filePath);
135 std::stringstream strStream;
136 strStream << inFile.rdbuf();
137 std::string str = strStream.str();
138 inFile.close();
139
140 if (!str.empty())
141 {
142 PropertyValue value{str};
143
144 DBusMapping dbusMapping{certObjPath + std::to_string(fileHandle),
145 certEntryIntf, "ClientCertificate",
146 "string"};
147 try
148 {
149 pldm::utils::DBusHandler().setDbusProperty(dbusMapping, value);
150 }
151 catch (const std::exception& e)
152 {
Sridevi Rameshe3b3f632022-06-14 05:28:15 -0500153 std::cerr
154 << "CertHandler::write:failed to set Client certificate, "
155 "ERROR="
156 << e.what() << "\n";
Varsha Kaverappa219ace92021-04-01 02:50:11 -0500157 return PLDM_ERROR;
158 }
159 PropertyValue valueStatus{
160 "xyz.openbmc_project.Certs.Entry.State.Complete"};
161 DBusMapping dbusMappingStatus{certObjPath +
162 std::to_string(fileHandle),
163 certEntryIntf, "Status", "string"};
164 try
165 {
Sridevi Rameshe3b3f632022-06-14 05:28:15 -0500166 std::cout
167 << "CertHandler::write:Client cert write, status: complete. File handle: "
168 << fileHandle << std::endl;
Varsha Kaverappa219ace92021-04-01 02:50:11 -0500169 pldm::utils::DBusHandler().setDbusProperty(dbusMappingStatus,
170 valueStatus);
171 }
172 catch (const std::exception& e)
173 {
174 std::cerr
Sridevi Rameshe3b3f632022-06-14 05:28:15 -0500175 << "CertHandler::write:failed to set status property of certicate entry, "
Varsha Kaverappa219ace92021-04-01 02:50:11 -0500176 "ERROR="
177 << e.what() << "\n";
178 return PLDM_ERROR;
179 }
180 fs::remove(filePath);
181 }
182 else
183 {
184 PropertyValue value{"xyz.openbmc_project.Certs.Entry.State.BadCSR"};
185 DBusMapping dbusMapping{certObjPath + std::to_string(fileHandle),
186 certEntryIntf, "Status", "string"};
187 try
188 {
Sridevi Rameshe3b3f632022-06-14 05:28:15 -0500189 std::cout
190 << "CertHandler::write:Client cert write, status: Bad CSR. File handle: "
191 << fileHandle << std::endl;
Varsha Kaverappa219ace92021-04-01 02:50:11 -0500192 pldm::utils::DBusHandler().setDbusProperty(dbusMapping, value);
193 }
194 catch (const std::exception& e)
195 {
196 std::cerr
Sridevi Rameshe3b3f632022-06-14 05:28:15 -0500197 << "CertHandler::write:failed to set status property of certicate entry, "
Varsha Kaverappa219ace92021-04-01 02:50:11 -0500198 "ERROR="
199 << e.what() << "\n";
200 return PLDM_ERROR;
201 }
202 }
203 }
Sampa Misrad823cc02020-03-24 04:53:20 -0500204 return PLDM_SUCCESS;
205}
206
207int CertHandler::newFileAvailable(uint64_t length)
208{
Varsha Kaverappa219ace92021-04-01 02:50:11 -0500209 fs::create_directories(certFilePath);
210 fs::permissions(certFilePath,
211 fs::perms::others_read | fs::perms::owner_write);
Sampa Misrad823cc02020-03-24 04:53:20 -0500212 int fileFd = -1;
213 int flags = O_WRONLY | O_CREAT | O_TRUNC;
Varsha Kaverappa219ace92021-04-01 02:50:11 -0500214 std::string filePath = certFilePath;
Sampa Misrad823cc02020-03-24 04:53:20 -0500215
216 if (certType == PLDM_FILE_TYPE_CERT_SIGNING_REQUEST)
217 {
218 return PLDM_ERROR_INVALID_DATA;
219 }
220 if (certType == PLDM_FILE_TYPE_SIGNED_CERT)
221 {
Sridevi Rameshe3b3f632022-06-14 05:28:15 -0500222 std::cout
223 << "CertHandler::newFileAvailable:new file available client cert file, file handle: "
224 << fileHandle << std::endl;
Varsha Kaverappa219ace92021-04-01 02:50:11 -0500225 fileFd = open(
226 (filePath + "ClientCert_" + std::to_string(fileHandle)).c_str(),
227 flags, S_IRUSR | S_IWUSR);
Sampa Misrad823cc02020-03-24 04:53:20 -0500228 }
229 else if (certType == PLDM_FILE_TYPE_ROOT_CERT)
230 {
Varsha Kaverappa219ace92021-04-01 02:50:11 -0500231 fileFd =
232 open((filePath + "RootCert").c_str(), flags, S_IRUSR | S_IWUSR);
Sampa Misrad823cc02020-03-24 04:53:20 -0500233 }
234 if (fileFd == -1)
235 {
Sridevi Rameshe3b3f632022-06-14 05:28:15 -0500236 std::cerr
237 << "CertHandler::newFileAvailable:failed to open file for type "
238 << certType << " ERROR=" << errno << "\n";
Sampa Misrad823cc02020-03-24 04:53:20 -0500239 return PLDM_ERROR;
240 }
241 certMap.emplace(certType, std::tuple(fileFd, length));
242 return PLDM_SUCCESS;
243}
244
Sridevi Rameshe3b3f632022-06-14 05:28:15 -0500245int CertHandler::newFileAvailableWithMetaData(uint64_t length,
246 uint32_t metaDataValue1,
247 uint32_t /*metaDataValue2*/,
248 uint32_t /*metaDataValue3*/,
249 uint32_t /*metaDataValue4*/)
250{
251 fs::create_directories(certFilePath);
252 fs::permissions(certFilePath,
253 fs::perms::others_read | fs::perms::owner_write);
254 int fileFd = -1;
255 int flags = O_WRONLY | O_CREAT | O_TRUNC;
256 std::string filePath = certFilePath;
257
258 if (certType == PLDM_FILE_TYPE_CERT_SIGNING_REQUEST)
259 {
260 return PLDM_ERROR_INVALID_DATA;
261 }
262 if (certType == PLDM_FILE_TYPE_SIGNED_CERT)
263 {
264 if (metaDataValue1 == PLDM_SUCCESS)
265 {
266 std::cerr
267 << "CertHandler::newFileAvailableWithMetaData:new file available client cert file, file handle: "
268 << fileHandle << std::endl;
269 fileFd = open(
270 (filePath + "ClientCert_" + std::to_string(fileHandle)).c_str(),
271 flags, S_IRUSR | S_IWUSR);
272 }
273 else if (metaDataValue1 == PLDM_INVALID_CERT_DATA)
274 {
275 std::cerr
276 << "newFileAvailableWithMetaData:client cert file Invalid data, file handle: "
277 << fileHandle << std::endl;
278 DBusMapping dbusMapping{certObjPath + std::to_string(fileHandle),
279 certEntryIntf, "Status", "string"};
280 std::string status = "xyz.openbmc_project.Certs.Entry.State.BadCSR";
281 PropertyValue value{status};
282 try
283 {
284 pldm::utils::DBusHandler().setDbusProperty(dbusMapping, value);
285 }
286 catch (const std::exception& e)
287 {
288 std::cerr
289 << "newFileAvailableWithMetaData:Failed to set status property of certicate entry, "
290 "ERROR="
291 << e.what() << "\n";
292 return PLDM_ERROR;
293 }
294 }
295 }
296 else if (certType == PLDM_FILE_TYPE_ROOT_CERT)
297 {
298 fileFd =
299 open((filePath + "RootCert").c_str(), flags, S_IRUSR | S_IWUSR);
300 }
301 if (fileFd == -1)
302 {
303 std::cerr
304 << "newFileAvailableWithMetaData:failed to open file for type "
305 << certType << " ERROR=" << errno << "\n";
306 return PLDM_ERROR;
307 }
308 certMap.emplace(certType, std::tuple(fileFd, length));
309 return PLDM_SUCCESS;
310}
311
312int CertHandler::fileAckWithMetaData(uint8_t fileStatus,
313 uint32_t /*metaDataValue1*/,
314 uint32_t /*metaDataValue2*/,
315 uint32_t /*metaDataValue3*/,
316 uint32_t /*metaDataValue4*/)
317{
318 if (certType == PLDM_FILE_TYPE_CERT_SIGNING_REQUEST)
319 {
320 DBusMapping dbusMapping{certObjPath + std::to_string(fileHandle),
321 certEntryIntf, "Status", "string"};
322 PropertyValue value = "xyz.openbmc_project.Certs.Entry.State.Pending";
323 if (fileStatus == PLDM_ERROR_INVALID_DATA)
324 {
325 value = "xyz.openbmc_project.Certs.Entry.State.BadCSR";
326 }
327 else if (fileStatus == PLDM_ERROR_NOT_READY)
328 {
329 value = "xyz.openbmc_project.Certs.Entry.State.Pending";
330 }
331 try
332 {
333 pldm::utils::DBusHandler().setDbusProperty(dbusMapping, value);
334 }
335 catch (const std::exception& e)
336 {
337 std::cerr
338 << "CertHandler::fileAckWithMetaData:Failed to set status property of certicate entry, "
339 "ERROR="
340 << e.what() << "\n";
341 return PLDM_ERROR;
342 }
343 }
344 return PLDM_SUCCESS;
345}
346
Sampa Misrad823cc02020-03-24 04:53:20 -0500347} // namespace responder
348} // namespace pldm