blob: 83d082ee87df8a3643781a1b160d61ee88f93ef4 [file] [log] [blame]
Sampa Misrad823cc02020-03-24 04:53:20 -05001#include "file_io_type_cert.hpp"
2
George Liu6492f522020-06-16 10:34:05 +08003#include "libpldm/base.h"
4#include "oem/ibm/libpldm/file_io.h"
5
Deepak Kodihallid130e1a2020-06-17 05:55:32 -05006#include "common/utils.hpp"
Sampa Misrad823cc02020-03-24 04:53:20 -05007
8#include <stdint.h>
9
10#include <iostream>
11
Sampa Misrad823cc02020-03-24 04:53:20 -050012namespace pldm
13{
Brad Bishop5079ac42021-08-19 18:35:06 -040014using namespace utils;
15
Sampa Misrad823cc02020-03-24 04:53:20 -050016namespace responder
17{
Sridevi Rameshe3b3f632022-06-14 05:28:15 -050018constexpr auto certObjPath = "/xyz/openbmc_project/certs/ca/entry/";
19constexpr auto certEntryIntf = "xyz.openbmc_project.Certs.Entry";
Varsha Kaverappa219ace92021-04-01 02:50:11 -050020static constexpr auto certFilePath = "/var/lib/ibm/bmcweb/";
Sampa Misrad823cc02020-03-24 04:53:20 -050021
22CertMap CertHandler::certMap;
23
24int CertHandler::writeFromMemory(uint32_t offset, uint32_t length,
Sampa Misra69508502020-09-08 00:08:21 -050025 uint64_t address,
26 oem_platform::Handler* /*oemPlatformHandler*/)
Sampa Misrad823cc02020-03-24 04:53:20 -050027{
28 auto it = certMap.find(certType);
29 if (it == certMap.end())
30 {
Sridevi Rameshe3b3f632022-06-14 05:28:15 -050031 std::cerr << "CertHandler::writeFromMemory:file for type " << certType
32 << " doesn't exist\n";
Sampa Misrad823cc02020-03-24 04:53:20 -050033 return PLDM_ERROR;
34 }
35
36 auto fd = std::get<0>(it->second);
37 auto& remSize = std::get<1>(it->second);
38 auto rc = transferFileData(fd, false, offset, length, address);
39 if (rc == PLDM_SUCCESS)
40 {
41 remSize -= length;
42 if (!remSize)
43 {
44 close(fd);
45 certMap.erase(it);
46 }
47 }
48 return rc;
49}
50
51int CertHandler::readIntoMemory(uint32_t offset, uint32_t& length,
Sampa Misra69508502020-09-08 00:08:21 -050052 uint64_t address,
53 oem_platform::Handler* /*oemPlatformHandler*/)
Sampa Misrad823cc02020-03-24 04:53:20 -050054{
Varsha Kaverappa219ace92021-04-01 02:50:11 -050055 std::string filePath = certFilePath;
56 filePath += "CSR_" + std::to_string(fileHandle);
Sampa Misrad823cc02020-03-24 04:53:20 -050057 if (certType != PLDM_FILE_TYPE_CERT_SIGNING_REQUEST)
58 {
59 return PLDM_ERROR_INVALID_DATA;
60 }
Varsha Kaverappa219ace92021-04-01 02:50:11 -050061 auto rc = transferFileData(filePath.c_str(), true, offset, length, address);
62 fs::remove(filePath);
63 if (rc)
64 {
65 return PLDM_ERROR;
66 }
67 return PLDM_SUCCESS;
Sampa Misrad823cc02020-03-24 04:53:20 -050068}
69
Sampa Misra69508502020-09-08 00:08:21 -050070int CertHandler::read(uint32_t offset, uint32_t& length, Response& response,
71 oem_platform::Handler* /*oemPlatformHandler*/)
Sampa Misrad823cc02020-03-24 04:53:20 -050072{
Sridevi Rameshe3b3f632022-06-14 05:28:15 -050073 std::cout
74 << "CertHandler::read:Read file response for Sign CSR, file handle: "
75 << fileHandle << std::endl;
Varsha Kaverappa219ace92021-04-01 02:50:11 -050076 std::string filePath = certFilePath;
77 filePath += "CSR_" + std::to_string(fileHandle);
Sampa Misrad823cc02020-03-24 04:53:20 -050078 if (certType != PLDM_FILE_TYPE_CERT_SIGNING_REQUEST)
79 {
80 return PLDM_ERROR_INVALID_DATA;
81 }
Varsha Kaverappa219ace92021-04-01 02:50:11 -050082 auto rc = readFile(filePath.c_str(), offset, length, response);
83 fs::remove(filePath);
84 if (rc)
85 {
86 return PLDM_ERROR;
87 }
88 return PLDM_SUCCESS;
Sampa Misrad823cc02020-03-24 04:53:20 -050089}
90
Sampa Misra69508502020-09-08 00:08:21 -050091int CertHandler::write(const char* buffer, uint32_t offset, uint32_t& length,
92 oem_platform::Handler* /*oemPlatformHandler*/)
Sampa Misrad823cc02020-03-24 04:53:20 -050093{
94 auto it = certMap.find(certType);
95 if (it == certMap.end())
96 {
Sridevi Rameshe3b3f632022-06-14 05:28:15 -050097 std::cerr << "CertHandler::write:file for type " << certType
98 << " doesn't exist\n";
Sampa Misrad823cc02020-03-24 04:53:20 -050099 return PLDM_ERROR;
100 }
101
102 auto fd = std::get<0>(it->second);
103 int rc = lseek(fd, offset, SEEK_SET);
104 if (rc == -1)
105 {
Sridevi Rameshe3b3f632022-06-14 05:28:15 -0500106 std::cerr << "CertHandler::write:lseek failed, ERROR=" << errno
107 << ", OFFSET=" << offset << "\n";
Sampa Misrad823cc02020-03-24 04:53:20 -0500108 return PLDM_ERROR;
109 }
110 rc = ::write(fd, buffer, length);
111 if (rc == -1)
112 {
Sridevi Rameshe3b3f632022-06-14 05:28:15 -0500113 std::cerr << "CertHandler::write:file write failed, ERROR=" << errno
Sampa Misrad823cc02020-03-24 04:53:20 -0500114 << ", LENGTH=" << length << ", OFFSET=" << offset << "\n";
115 return PLDM_ERROR;
116 }
117 length = rc;
118 auto& remSize = std::get<1>(it->second);
119 remSize -= length;
120 if (!remSize)
121 {
122 close(fd);
123 certMap.erase(it);
124 }
Varsha Kaverappa219ace92021-04-01 02:50:11 -0500125
126 if (certType == PLDM_FILE_TYPE_SIGNED_CERT)
127 {
128 constexpr auto certObjPath = "/xyz/openbmc_project/certs/ca/entry/";
129 constexpr auto certEntryIntf = "xyz.openbmc_project.Certs.Entry";
130
131 std::string filePath = certFilePath;
132 filePath += "ClientCert_" + std::to_string(fileHandle);
133
134 std::ifstream inFile;
135 inFile.open(filePath);
136 std::stringstream strStream;
137 strStream << inFile.rdbuf();
138 std::string str = strStream.str();
139 inFile.close();
140
141 if (!str.empty())
142 {
143 PropertyValue value{str};
144
145 DBusMapping dbusMapping{certObjPath + std::to_string(fileHandle),
146 certEntryIntf, "ClientCertificate",
147 "string"};
148 try
149 {
150 pldm::utils::DBusHandler().setDbusProperty(dbusMapping, value);
151 }
152 catch (const std::exception& e)
153 {
Sridevi Rameshe3b3f632022-06-14 05:28:15 -0500154 std::cerr
155 << "CertHandler::write:failed to set Client certificate, "
156 "ERROR="
157 << e.what() << "\n";
Varsha Kaverappa219ace92021-04-01 02:50:11 -0500158 return PLDM_ERROR;
159 }
160 PropertyValue valueStatus{
161 "xyz.openbmc_project.Certs.Entry.State.Complete"};
162 DBusMapping dbusMappingStatus{certObjPath +
163 std::to_string(fileHandle),
164 certEntryIntf, "Status", "string"};
165 try
166 {
Sridevi Rameshe3b3f632022-06-14 05:28:15 -0500167 std::cout
168 << "CertHandler::write:Client cert write, status: complete. File handle: "
169 << fileHandle << std::endl;
Varsha Kaverappa219ace92021-04-01 02:50:11 -0500170 pldm::utils::DBusHandler().setDbusProperty(dbusMappingStatus,
171 valueStatus);
172 }
173 catch (const std::exception& e)
174 {
175 std::cerr
Sridevi Rameshe3b3f632022-06-14 05:28:15 -0500176 << "CertHandler::write:failed to set status property of certicate entry, "
Varsha Kaverappa219ace92021-04-01 02:50:11 -0500177 "ERROR="
178 << e.what() << "\n";
179 return PLDM_ERROR;
180 }
181 fs::remove(filePath);
182 }
183 else
184 {
185 PropertyValue value{"xyz.openbmc_project.Certs.Entry.State.BadCSR"};
186 DBusMapping dbusMapping{certObjPath + std::to_string(fileHandle),
187 certEntryIntf, "Status", "string"};
188 try
189 {
Sridevi Rameshe3b3f632022-06-14 05:28:15 -0500190 std::cout
191 << "CertHandler::write:Client cert write, status: Bad CSR. File handle: "
192 << fileHandle << std::endl;
Varsha Kaverappa219ace92021-04-01 02:50:11 -0500193 pldm::utils::DBusHandler().setDbusProperty(dbusMapping, value);
194 }
195 catch (const std::exception& e)
196 {
197 std::cerr
Sridevi Rameshe3b3f632022-06-14 05:28:15 -0500198 << "CertHandler::write:failed to set status property of certicate entry, "
Varsha Kaverappa219ace92021-04-01 02:50:11 -0500199 "ERROR="
200 << e.what() << "\n";
201 return PLDM_ERROR;
202 }
203 }
204 }
Sampa Misrad823cc02020-03-24 04:53:20 -0500205 return PLDM_SUCCESS;
206}
207
208int CertHandler::newFileAvailable(uint64_t length)
209{
Varsha Kaverappa219ace92021-04-01 02:50:11 -0500210 fs::create_directories(certFilePath);
211 fs::permissions(certFilePath,
212 fs::perms::others_read | fs::perms::owner_write);
Sampa Misrad823cc02020-03-24 04:53:20 -0500213 int fileFd = -1;
214 int flags = O_WRONLY | O_CREAT | O_TRUNC;
Varsha Kaverappa219ace92021-04-01 02:50:11 -0500215 std::string filePath = certFilePath;
Sampa Misrad823cc02020-03-24 04:53:20 -0500216
217 if (certType == PLDM_FILE_TYPE_CERT_SIGNING_REQUEST)
218 {
219 return PLDM_ERROR_INVALID_DATA;
220 }
221 if (certType == PLDM_FILE_TYPE_SIGNED_CERT)
222 {
Sridevi Rameshe3b3f632022-06-14 05:28:15 -0500223 std::cout
224 << "CertHandler::newFileAvailable:new file available client cert file, file handle: "
225 << fileHandle << std::endl;
Varsha Kaverappa219ace92021-04-01 02:50:11 -0500226 fileFd = open(
227 (filePath + "ClientCert_" + std::to_string(fileHandle)).c_str(),
228 flags, S_IRUSR | S_IWUSR);
Sampa Misrad823cc02020-03-24 04:53:20 -0500229 }
230 else if (certType == PLDM_FILE_TYPE_ROOT_CERT)
231 {
Varsha Kaverappa219ace92021-04-01 02:50:11 -0500232 fileFd =
233 open((filePath + "RootCert").c_str(), flags, S_IRUSR | S_IWUSR);
Sampa Misrad823cc02020-03-24 04:53:20 -0500234 }
235 if (fileFd == -1)
236 {
Sridevi Rameshe3b3f632022-06-14 05:28:15 -0500237 std::cerr
238 << "CertHandler::newFileAvailable:failed to open file for type "
239 << certType << " ERROR=" << errno << "\n";
Sampa Misrad823cc02020-03-24 04:53:20 -0500240 return PLDM_ERROR;
241 }
242 certMap.emplace(certType, std::tuple(fileFd, length));
243 return PLDM_SUCCESS;
244}
245
Sridevi Rameshe3b3f632022-06-14 05:28:15 -0500246int CertHandler::newFileAvailableWithMetaData(uint64_t length,
247 uint32_t metaDataValue1,
248 uint32_t /*metaDataValue2*/,
249 uint32_t /*metaDataValue3*/,
250 uint32_t /*metaDataValue4*/)
251{
252 fs::create_directories(certFilePath);
253 fs::permissions(certFilePath,
254 fs::perms::others_read | fs::perms::owner_write);
255 int fileFd = -1;
256 int flags = O_WRONLY | O_CREAT | O_TRUNC;
257 std::string filePath = certFilePath;
258
259 if (certType == PLDM_FILE_TYPE_CERT_SIGNING_REQUEST)
260 {
261 return PLDM_ERROR_INVALID_DATA;
262 }
263 if (certType == PLDM_FILE_TYPE_SIGNED_CERT)
264 {
265 if (metaDataValue1 == PLDM_SUCCESS)
266 {
267 std::cerr
268 << "CertHandler::newFileAvailableWithMetaData:new file available client cert file, file handle: "
269 << fileHandle << std::endl;
270 fileFd = open(
271 (filePath + "ClientCert_" + std::to_string(fileHandle)).c_str(),
272 flags, S_IRUSR | S_IWUSR);
273 }
274 else if (metaDataValue1 == PLDM_INVALID_CERT_DATA)
275 {
276 std::cerr
277 << "newFileAvailableWithMetaData:client cert file Invalid data, file handle: "
278 << fileHandle << std::endl;
279 DBusMapping dbusMapping{certObjPath + std::to_string(fileHandle),
280 certEntryIntf, "Status", "string"};
281 std::string status = "xyz.openbmc_project.Certs.Entry.State.BadCSR";
282 PropertyValue value{status};
283 try
284 {
285 pldm::utils::DBusHandler().setDbusProperty(dbusMapping, value);
286 }
287 catch (const std::exception& e)
288 {
289 std::cerr
290 << "newFileAvailableWithMetaData:Failed to set status property of certicate entry, "
291 "ERROR="
292 << e.what() << "\n";
293 return PLDM_ERROR;
294 }
295 }
296 }
297 else if (certType == PLDM_FILE_TYPE_ROOT_CERT)
298 {
299 fileFd =
300 open((filePath + "RootCert").c_str(), flags, S_IRUSR | S_IWUSR);
301 }
302 if (fileFd == -1)
303 {
304 std::cerr
305 << "newFileAvailableWithMetaData:failed to open file for type "
306 << certType << " ERROR=" << errno << "\n";
307 return PLDM_ERROR;
308 }
309 certMap.emplace(certType, std::tuple(fileFd, length));
310 return PLDM_SUCCESS;
311}
312
313int CertHandler::fileAckWithMetaData(uint8_t fileStatus,
314 uint32_t /*metaDataValue1*/,
315 uint32_t /*metaDataValue2*/,
316 uint32_t /*metaDataValue3*/,
317 uint32_t /*metaDataValue4*/)
318{
319 if (certType == PLDM_FILE_TYPE_CERT_SIGNING_REQUEST)
320 {
321 DBusMapping dbusMapping{certObjPath + std::to_string(fileHandle),
322 certEntryIntf, "Status", "string"};
323 PropertyValue value = "xyz.openbmc_project.Certs.Entry.State.Pending";
324 if (fileStatus == PLDM_ERROR_INVALID_DATA)
325 {
326 value = "xyz.openbmc_project.Certs.Entry.State.BadCSR";
327 }
328 else if (fileStatus == PLDM_ERROR_NOT_READY)
329 {
330 value = "xyz.openbmc_project.Certs.Entry.State.Pending";
331 }
332 try
333 {
334 pldm::utils::DBusHandler().setDbusProperty(dbusMapping, value);
335 }
336 catch (const std::exception& e)
337 {
338 std::cerr
339 << "CertHandler::fileAckWithMetaData:Failed to set status property of certicate entry, "
340 "ERROR="
341 << e.what() << "\n";
342 return PLDM_ERROR;
343 }
344 }
345 return PLDM_SUCCESS;
346}
347
Sampa Misrad823cc02020-03-24 04:53:20 -0500348} // namespace responder
349} // namespace pldm