blob: 8d9b73ee016c51777652675d9675be00c0e57757 [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
Riya Dixit49cfb132023-03-02 04:26:53 -06009#include <phosphor-logging/lg2.hpp>
10
Sampa Misrad823cc02020-03-24 04:53:20 -050011#include <iostream>
12
Riya Dixit49cfb132023-03-02 04:26:53 -060013PHOSPHOR_LOG2_USING;
14
Sampa Misrad823cc02020-03-24 04:53:20 -050015namespace pldm
16{
Brad Bishop5079ac42021-08-19 18:35:06 -040017using namespace utils;
18
Sampa Misrad823cc02020-03-24 04:53:20 -050019namespace responder
20{
Sridevi Rameshe3b3f632022-06-14 05:28:15 -050021constexpr auto certObjPath = "/xyz/openbmc_project/certs/ca/entry/";
22constexpr auto certEntryIntf = "xyz.openbmc_project.Certs.Entry";
Varsha Kaverappa219ace92021-04-01 02:50:11 -050023static constexpr auto certFilePath = "/var/lib/ibm/bmcweb/";
Sampa Misrad823cc02020-03-24 04:53:20 -050024
25CertMap CertHandler::certMap;
26
27int CertHandler::writeFromMemory(uint32_t offset, uint32_t length,
Sampa Misra69508502020-09-08 00:08:21 -050028 uint64_t address,
29 oem_platform::Handler* /*oemPlatformHandler*/)
Sampa Misrad823cc02020-03-24 04:53:20 -050030{
31 auto it = certMap.find(certType);
32 if (it == certMap.end())
33 {
Riya Dixit49cfb132023-03-02 04:26:53 -060034 error(
35 "CertHandler::writeFromMemory:file for type {CERT_TYPE} doesn't exist",
36 "CERT_TYPE", certType);
Sampa Misrad823cc02020-03-24 04:53:20 -050037 return PLDM_ERROR;
38 }
39
40 auto fd = std::get<0>(it->second);
41 auto& remSize = std::get<1>(it->second);
42 auto rc = transferFileData(fd, false, offset, length, address);
43 if (rc == PLDM_SUCCESS)
44 {
45 remSize -= length;
46 if (!remSize)
47 {
48 close(fd);
49 certMap.erase(it);
50 }
51 }
52 return rc;
53}
54
55int CertHandler::readIntoMemory(uint32_t offset, uint32_t& length,
Sampa Misra69508502020-09-08 00:08:21 -050056 uint64_t address,
57 oem_platform::Handler* /*oemPlatformHandler*/)
Sampa Misrad823cc02020-03-24 04:53:20 -050058{
Varsha Kaverappa219ace92021-04-01 02:50:11 -050059 std::string filePath = certFilePath;
60 filePath += "CSR_" + std::to_string(fileHandle);
Sampa Misrad823cc02020-03-24 04:53:20 -050061 if (certType != PLDM_FILE_TYPE_CERT_SIGNING_REQUEST)
62 {
63 return PLDM_ERROR_INVALID_DATA;
64 }
Varsha Kaverappa219ace92021-04-01 02:50:11 -050065 auto rc = transferFileData(filePath.c_str(), true, offset, length, address);
66 fs::remove(filePath);
67 if (rc)
68 {
69 return PLDM_ERROR;
70 }
71 return PLDM_SUCCESS;
Sampa Misrad823cc02020-03-24 04:53:20 -050072}
73
Sampa Misra69508502020-09-08 00:08:21 -050074int CertHandler::read(uint32_t offset, uint32_t& length, Response& response,
75 oem_platform::Handler* /*oemPlatformHandler*/)
Sampa Misrad823cc02020-03-24 04:53:20 -050076{
Riya Dixit49cfb132023-03-02 04:26:53 -060077 info(
78 "CertHandler::read:Read file response for Sign CSR, file handle: {FILE_HANDLE}",
79 "FILE_HANDLE", fileHandle);
Varsha Kaverappa219ace92021-04-01 02:50:11 -050080 std::string filePath = certFilePath;
81 filePath += "CSR_" + std::to_string(fileHandle);
Sampa Misrad823cc02020-03-24 04:53:20 -050082 if (certType != PLDM_FILE_TYPE_CERT_SIGNING_REQUEST)
83 {
84 return PLDM_ERROR_INVALID_DATA;
85 }
Varsha Kaverappa219ace92021-04-01 02:50:11 -050086 auto rc = readFile(filePath.c_str(), offset, length, response);
87 fs::remove(filePath);
88 if (rc)
89 {
90 return PLDM_ERROR;
91 }
92 return PLDM_SUCCESS;
Sampa Misrad823cc02020-03-24 04:53:20 -050093}
94
Sampa Misra69508502020-09-08 00:08:21 -050095int CertHandler::write(const char* buffer, uint32_t offset, uint32_t& length,
96 oem_platform::Handler* /*oemPlatformHandler*/)
Sampa Misrad823cc02020-03-24 04:53:20 -050097{
98 auto it = certMap.find(certType);
99 if (it == certMap.end())
100 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600101 error("CertHandler::write:file for type {CERT_TYPE} doesn't exist",
102 "CERT_TYPE", certType);
Sampa Misrad823cc02020-03-24 04:53:20 -0500103 return PLDM_ERROR;
104 }
105
106 auto fd = std::get<0>(it->second);
107 int rc = lseek(fd, offset, SEEK_SET);
108 if (rc == -1)
109 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600110 error("CertHandler::write:lseek failed, ERROR={ERR}, OFFSET={OFFSET}",
111 "ERR", errno, "OFFSET", offset);
Sampa Misrad823cc02020-03-24 04:53:20 -0500112 return PLDM_ERROR;
113 }
114 rc = ::write(fd, buffer, length);
115 if (rc == -1)
116 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600117 error(
118 "CertHandler::write:file write failed, ERROR={ERR}, LENGTH={LEN}, OFFSET={OFFSET}",
119 "ERR", errno, "LEN", length, "OFFSET", offset);
Sampa Misrad823cc02020-03-24 04:53:20 -0500120 return PLDM_ERROR;
121 }
122 length = rc;
123 auto& remSize = std::get<1>(it->second);
124 remSize -= length;
125 if (!remSize)
126 {
127 close(fd);
128 certMap.erase(it);
129 }
Varsha Kaverappa219ace92021-04-01 02:50:11 -0500130
131 if (certType == PLDM_FILE_TYPE_SIGNED_CERT)
132 {
133 constexpr auto certObjPath = "/xyz/openbmc_project/certs/ca/entry/";
134 constexpr auto certEntryIntf = "xyz.openbmc_project.Certs.Entry";
135
136 std::string filePath = certFilePath;
137 filePath += "ClientCert_" + std::to_string(fileHandle);
138
139 std::ifstream inFile;
140 inFile.open(filePath);
141 std::stringstream strStream;
142 strStream << inFile.rdbuf();
143 std::string str = strStream.str();
144 inFile.close();
145
146 if (!str.empty())
147 {
148 PropertyValue value{str};
149
150 DBusMapping dbusMapping{certObjPath + std::to_string(fileHandle),
151 certEntryIntf, "ClientCertificate",
152 "string"};
153 try
154 {
155 pldm::utils::DBusHandler().setDbusProperty(dbusMapping, value);
156 }
157 catch (const std::exception& e)
158 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600159 error(
160 "CertHandler::write:failed to set Client certificate, ERROR={ERR_EXCEP}",
161 "ERR_EXCEP", e.what());
Varsha Kaverappa219ace92021-04-01 02:50:11 -0500162 return PLDM_ERROR;
163 }
164 PropertyValue valueStatus{
165 "xyz.openbmc_project.Certs.Entry.State.Complete"};
166 DBusMapping dbusMappingStatus{certObjPath +
167 std::to_string(fileHandle),
168 certEntryIntf, "Status", "string"};
169 try
170 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600171 info(
172 "CertHandler::write:Client cert write, status: complete. File handle: {FILE_HANDLE}",
173 "FILE_HANDLE", fileHandle);
Varsha Kaverappa219ace92021-04-01 02:50:11 -0500174 pldm::utils::DBusHandler().setDbusProperty(dbusMappingStatus,
175 valueStatus);
176 }
177 catch (const std::exception& e)
178 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600179 error(
180 "CertHandler::write:failed to set status property of certicate entry, ERROR={ERR_EXCEP}",
181 "ERR_EXCEP", e.what());
Varsha Kaverappa219ace92021-04-01 02:50:11 -0500182 return PLDM_ERROR;
183 }
184 fs::remove(filePath);
185 }
186 else
187 {
188 PropertyValue value{"xyz.openbmc_project.Certs.Entry.State.BadCSR"};
189 DBusMapping dbusMapping{certObjPath + std::to_string(fileHandle),
190 certEntryIntf, "Status", "string"};
191 try
192 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600193 info(
194 "CertHandler::write:Client cert write, status: Bad CSR. File handle: {FILE_HANDLE}",
195 "FILE_HANDLE", fileHandle);
Varsha Kaverappa219ace92021-04-01 02:50:11 -0500196 pldm::utils::DBusHandler().setDbusProperty(dbusMapping, value);
197 }
198 catch (const std::exception& e)
199 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600200 error(
201 "CertHandler::write:failed to set status property of certicate entry, {ERR_EXCEP}",
202 "ERR_EXCEP", e.what());
Varsha Kaverappa219ace92021-04-01 02:50:11 -0500203 return PLDM_ERROR;
204 }
205 }
206 }
Sampa Misrad823cc02020-03-24 04:53:20 -0500207 return PLDM_SUCCESS;
208}
209
210int CertHandler::newFileAvailable(uint64_t length)
211{
Varsha Kaverappa219ace92021-04-01 02:50:11 -0500212 fs::create_directories(certFilePath);
213 fs::permissions(certFilePath,
214 fs::perms::others_read | fs::perms::owner_write);
Sampa Misrad823cc02020-03-24 04:53:20 -0500215 int fileFd = -1;
216 int flags = O_WRONLY | O_CREAT | O_TRUNC;
Varsha Kaverappa219ace92021-04-01 02:50:11 -0500217 std::string filePath = certFilePath;
Sampa Misrad823cc02020-03-24 04:53:20 -0500218
219 if (certType == PLDM_FILE_TYPE_CERT_SIGNING_REQUEST)
220 {
221 return PLDM_ERROR_INVALID_DATA;
222 }
223 if (certType == PLDM_FILE_TYPE_SIGNED_CERT)
224 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600225 info(
226 "CertHandler::newFileAvailable:new file available client cert file, file handle: {FILE_HANDLE}",
227 "FILE_HANDLE", fileHandle);
Varsha Kaverappa219ace92021-04-01 02:50:11 -0500228 fileFd = open(
229 (filePath + "ClientCert_" + std::to_string(fileHandle)).c_str(),
230 flags, S_IRUSR | S_IWUSR);
Sampa Misrad823cc02020-03-24 04:53:20 -0500231 }
232 else if (certType == PLDM_FILE_TYPE_ROOT_CERT)
233 {
Varsha Kaverappa219ace92021-04-01 02:50:11 -0500234 fileFd =
235 open((filePath + "RootCert").c_str(), flags, S_IRUSR | S_IWUSR);
Sampa Misrad823cc02020-03-24 04:53:20 -0500236 }
237 if (fileFd == -1)
238 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600239 error(
240 "CertHandler::newFileAvailable:failed to open file for type {CERT_TYPE} ERROR={ERR}",
241 "CERT_TYPE", certType, "ERR", errno);
Sampa Misrad823cc02020-03-24 04:53:20 -0500242 return PLDM_ERROR;
243 }
244 certMap.emplace(certType, std::tuple(fileFd, length));
245 return PLDM_SUCCESS;
246}
247
Sridevi Rameshe3b3f632022-06-14 05:28:15 -0500248int CertHandler::newFileAvailableWithMetaData(uint64_t length,
249 uint32_t metaDataValue1,
250 uint32_t /*metaDataValue2*/,
251 uint32_t /*metaDataValue3*/,
252 uint32_t /*metaDataValue4*/)
253{
254 fs::create_directories(certFilePath);
255 fs::permissions(certFilePath,
256 fs::perms::others_read | fs::perms::owner_write);
257 int fileFd = -1;
258 int flags = O_WRONLY | O_CREAT | O_TRUNC;
259 std::string filePath = certFilePath;
260
261 if (certType == PLDM_FILE_TYPE_CERT_SIGNING_REQUEST)
262 {
263 return PLDM_ERROR_INVALID_DATA;
264 }
265 if (certType == PLDM_FILE_TYPE_SIGNED_CERT)
266 {
267 if (metaDataValue1 == PLDM_SUCCESS)
268 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600269 error(
270 "CertHandler::newFileAvailableWithMetaData:new file available client cert file, file handle: {FILE_HANDLE}",
271 "FILE_HANDLE", fileHandle);
Sridevi Rameshe3b3f632022-06-14 05:28:15 -0500272 fileFd = open(
273 (filePath + "ClientCert_" + std::to_string(fileHandle)).c_str(),
274 flags, S_IRUSR | S_IWUSR);
275 }
276 else if (metaDataValue1 == PLDM_INVALID_CERT_DATA)
277 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600278 error(
279 "newFileAvailableWithMetaData:client cert file Invalid data, file handle: {FILE_HANDLE}",
280 "FILE_HANDLE", fileHandle);
Sridevi Rameshe3b3f632022-06-14 05:28:15 -0500281 DBusMapping dbusMapping{certObjPath + std::to_string(fileHandle),
282 certEntryIntf, "Status", "string"};
283 std::string status = "xyz.openbmc_project.Certs.Entry.State.BadCSR";
284 PropertyValue value{status};
285 try
286 {
287 pldm::utils::DBusHandler().setDbusProperty(dbusMapping, value);
288 }
289 catch (const std::exception& e)
290 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600291 error(
292 "newFileAvailableWithMetaData:Failed to set status property of certicate entry, ERROR= {ERR_EXCEP}",
293 "ERR_EXCEP", e.what());
Sridevi Rameshe3b3f632022-06-14 05:28:15 -0500294 return PLDM_ERROR;
295 }
296 }
297 }
298 else if (certType == PLDM_FILE_TYPE_ROOT_CERT)
299 {
300 fileFd =
301 open((filePath + "RootCert").c_str(), flags, S_IRUSR | S_IWUSR);
302 }
303 if (fileFd == -1)
304 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600305 error(
306 "newFileAvailableWithMetaData:failed to open file for type {CERT_TYPE} ERROR={ERR}",
307 "CERT_TYPE", certType, "ERR", errno);
Sridevi Rameshe3b3f632022-06-14 05:28:15 -0500308 return PLDM_ERROR;
309 }
310 certMap.emplace(certType, std::tuple(fileFd, length));
311 return PLDM_SUCCESS;
312}
313
314int CertHandler::fileAckWithMetaData(uint8_t fileStatus,
315 uint32_t /*metaDataValue1*/,
316 uint32_t /*metaDataValue2*/,
317 uint32_t /*metaDataValue3*/,
318 uint32_t /*metaDataValue4*/)
319{
320 if (certType == PLDM_FILE_TYPE_CERT_SIGNING_REQUEST)
321 {
322 DBusMapping dbusMapping{certObjPath + std::to_string(fileHandle),
323 certEntryIntf, "Status", "string"};
324 PropertyValue value = "xyz.openbmc_project.Certs.Entry.State.Pending";
325 if (fileStatus == PLDM_ERROR_INVALID_DATA)
326 {
327 value = "xyz.openbmc_project.Certs.Entry.State.BadCSR";
328 }
329 else if (fileStatus == PLDM_ERROR_NOT_READY)
330 {
331 value = "xyz.openbmc_project.Certs.Entry.State.Pending";
332 }
333 try
334 {
335 pldm::utils::DBusHandler().setDbusProperty(dbusMapping, value);
336 }
337 catch (const std::exception& e)
338 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600339 error(
340 "CertHandler::fileAckWithMetaData:Failed to set status property of certicate entry, ERROR={ERR_EXCEP}",
341 "ERR_EXCEP", e.what());
Sridevi Rameshe3b3f632022-06-14 05:28:15 -0500342 return PLDM_ERROR;
343 }
344 }
345 return PLDM_SUCCESS;
346}
347
Sampa Misrad823cc02020-03-24 04:53:20 -0500348} // namespace responder
349} // namespace pldm