blob: a5b4e216d6bc09727e98d04e5f6ecfa441ef7d69 [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>
Andrew Jeffery21f128d2024-01-15 15:34:26 +10306#include <libpldm/oem/ibm/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
Riya Dixit49cfb132023-03-02 04:26:53 -060011PHOSPHOR_LOG2_USING;
12
Sampa Misrad823cc02020-03-24 04:53:20 -050013namespace pldm
14{
Brad Bishop5079ac42021-08-19 18:35:06 -040015using namespace utils;
16
Sampa Misrad823cc02020-03-24 04:53:20 -050017namespace responder
18{
Sridevi Rameshe3b3f632022-06-14 05:28:15 -050019constexpr auto certObjPath = "/xyz/openbmc_project/certs/ca/entry/";
20constexpr auto certEntryIntf = "xyz.openbmc_project.Certs.Entry";
Varsha Kaverappa219ace92021-04-01 02:50:11 -050021static constexpr auto certFilePath = "/var/lib/ibm/bmcweb/";
Sampa Misrad823cc02020-03-24 04:53:20 -050022
23CertMap CertHandler::certMap;
24
25int CertHandler::writeFromMemory(uint32_t offset, uint32_t length,
Sampa Misra69508502020-09-08 00:08:21 -050026 uint64_t address,
27 oem_platform::Handler* /*oemPlatformHandler*/)
Sampa Misrad823cc02020-03-24 04:53:20 -050028{
29 auto it = certMap.find(certType);
30 if (it == certMap.end())
31 {
Riya Dixit49cfb132023-03-02 04:26:53 -060032 error(
33 "CertHandler::writeFromMemory:file for type {CERT_TYPE} doesn't exist",
34 "CERT_TYPE", certType);
Sampa Misrad823cc02020-03-24 04:53:20 -050035 return PLDM_ERROR;
36 }
37
38 auto fd = std::get<0>(it->second);
39 auto& remSize = std::get<1>(it->second);
40 auto rc = transferFileData(fd, false, offset, length, address);
41 if (rc == PLDM_SUCCESS)
42 {
43 remSize -= length;
44 if (!remSize)
45 {
46 close(fd);
47 certMap.erase(it);
48 }
49 }
50 return rc;
51}
52
53int CertHandler::readIntoMemory(uint32_t offset, uint32_t& length,
Sampa Misra69508502020-09-08 00:08:21 -050054 uint64_t address,
55 oem_platform::Handler* /*oemPlatformHandler*/)
Sampa Misrad823cc02020-03-24 04:53:20 -050056{
Varsha Kaverappa219ace92021-04-01 02:50:11 -050057 std::string filePath = certFilePath;
58 filePath += "CSR_" + std::to_string(fileHandle);
Sampa Misrad823cc02020-03-24 04:53:20 -050059 if (certType != PLDM_FILE_TYPE_CERT_SIGNING_REQUEST)
60 {
61 return PLDM_ERROR_INVALID_DATA;
62 }
Varsha Kaverappa219ace92021-04-01 02:50:11 -050063 auto rc = transferFileData(filePath.c_str(), true, offset, length, address);
64 fs::remove(filePath);
65 if (rc)
66 {
67 return PLDM_ERROR;
68 }
69 return PLDM_SUCCESS;
Sampa Misrad823cc02020-03-24 04:53:20 -050070}
71
Sampa Misra69508502020-09-08 00:08:21 -050072int CertHandler::read(uint32_t offset, uint32_t& length, Response& response,
73 oem_platform::Handler* /*oemPlatformHandler*/)
Sampa Misrad823cc02020-03-24 04:53:20 -050074{
Riya Dixit49cfb132023-03-02 04:26:53 -060075 info(
76 "CertHandler::read:Read file response for Sign CSR, file handle: {FILE_HANDLE}",
77 "FILE_HANDLE", fileHandle);
Varsha Kaverappa219ace92021-04-01 02:50:11 -050078 std::string filePath = certFilePath;
79 filePath += "CSR_" + std::to_string(fileHandle);
Sampa Misrad823cc02020-03-24 04:53:20 -050080 if (certType != PLDM_FILE_TYPE_CERT_SIGNING_REQUEST)
81 {
82 return PLDM_ERROR_INVALID_DATA;
83 }
Varsha Kaverappa219ace92021-04-01 02:50:11 -050084 auto rc = readFile(filePath.c_str(), offset, length, response);
85 fs::remove(filePath);
86 if (rc)
87 {
88 return PLDM_ERROR;
89 }
90 return PLDM_SUCCESS;
Sampa Misrad823cc02020-03-24 04:53:20 -050091}
92
Sampa Misra69508502020-09-08 00:08:21 -050093int CertHandler::write(const char* buffer, uint32_t offset, uint32_t& length,
94 oem_platform::Handler* /*oemPlatformHandler*/)
Sampa Misrad823cc02020-03-24 04:53:20 -050095{
96 auto it = certMap.find(certType);
97 if (it == certMap.end())
98 {
Riya Dixit49cfb132023-03-02 04:26:53 -060099 error("CertHandler::write:file for type {CERT_TYPE} doesn't exist",
100 "CERT_TYPE", certType);
Sampa Misrad823cc02020-03-24 04:53:20 -0500101 return PLDM_ERROR;
102 }
103
104 auto fd = std::get<0>(it->second);
105 int rc = lseek(fd, offset, SEEK_SET);
106 if (rc == -1)
107 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600108 error("CertHandler::write:lseek failed, ERROR={ERR}, OFFSET={OFFSET}",
109 "ERR", errno, "OFFSET", offset);
Sampa Misrad823cc02020-03-24 04:53:20 -0500110 return PLDM_ERROR;
111 }
112 rc = ::write(fd, buffer, length);
113 if (rc == -1)
114 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600115 error(
116 "CertHandler::write:file write failed, ERROR={ERR}, LENGTH={LEN}, OFFSET={OFFSET}",
117 "ERR", errno, "LEN", length, "OFFSET", offset);
Sampa Misrad823cc02020-03-24 04:53:20 -0500118 return PLDM_ERROR;
119 }
120 length = rc;
121 auto& remSize = std::get<1>(it->second);
122 remSize -= length;
123 if (!remSize)
124 {
125 close(fd);
126 certMap.erase(it);
127 }
Varsha Kaverappa219ace92021-04-01 02:50:11 -0500128
129 if (certType == PLDM_FILE_TYPE_SIGNED_CERT)
130 {
131 constexpr auto certObjPath = "/xyz/openbmc_project/certs/ca/entry/";
132 constexpr auto certEntryIntf = "xyz.openbmc_project.Certs.Entry";
133
134 std::string filePath = certFilePath;
135 filePath += "ClientCert_" + std::to_string(fileHandle);
136
137 std::ifstream inFile;
138 inFile.open(filePath);
139 std::stringstream strStream;
140 strStream << inFile.rdbuf();
141 std::string str = strStream.str();
142 inFile.close();
143
144 if (!str.empty())
145 {
146 PropertyValue value{str};
147
148 DBusMapping dbusMapping{certObjPath + std::to_string(fileHandle),
149 certEntryIntf, "ClientCertificate",
150 "string"};
151 try
152 {
153 pldm::utils::DBusHandler().setDbusProperty(dbusMapping, value);
154 }
155 catch (const std::exception& e)
156 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600157 error(
158 "CertHandler::write:failed to set Client certificate, ERROR={ERR_EXCEP}",
159 "ERR_EXCEP", e.what());
Varsha Kaverappa219ace92021-04-01 02:50:11 -0500160 return PLDM_ERROR;
161 }
162 PropertyValue valueStatus{
163 "xyz.openbmc_project.Certs.Entry.State.Complete"};
164 DBusMapping dbusMappingStatus{certObjPath +
165 std::to_string(fileHandle),
166 certEntryIntf, "Status", "string"};
167 try
168 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600169 info(
170 "CertHandler::write:Client cert write, status: complete. File handle: {FILE_HANDLE}",
171 "FILE_HANDLE", fileHandle);
Varsha Kaverappa219ace92021-04-01 02:50:11 -0500172 pldm::utils::DBusHandler().setDbusProperty(dbusMappingStatus,
173 valueStatus);
174 }
175 catch (const std::exception& e)
176 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600177 error(
178 "CertHandler::write:failed to set status property of certicate entry, ERROR={ERR_EXCEP}",
179 "ERR_EXCEP", e.what());
Varsha Kaverappa219ace92021-04-01 02:50:11 -0500180 return PLDM_ERROR;
181 }
182 fs::remove(filePath);
183 }
184 else
185 {
186 PropertyValue value{"xyz.openbmc_project.Certs.Entry.State.BadCSR"};
187 DBusMapping dbusMapping{certObjPath + std::to_string(fileHandle),
188 certEntryIntf, "Status", "string"};
189 try
190 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600191 info(
192 "CertHandler::write:Client cert write, status: Bad CSR. File handle: {FILE_HANDLE}",
193 "FILE_HANDLE", fileHandle);
Varsha Kaverappa219ace92021-04-01 02:50:11 -0500194 pldm::utils::DBusHandler().setDbusProperty(dbusMapping, value);
195 }
196 catch (const std::exception& e)
197 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600198 error(
199 "CertHandler::write:failed to set status property of certicate entry, {ERR_EXCEP}",
200 "ERR_EXCEP", e.what());
Varsha Kaverappa219ace92021-04-01 02:50:11 -0500201 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 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600223 info(
224 "CertHandler::newFileAvailable:new file available client cert file, file handle: {FILE_HANDLE}",
225 "FILE_HANDLE", fileHandle);
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 {
Patrick Williams6da4f912023-05-10 07:50:53 -0500232 fileFd = open((filePath + "RootCert").c_str(), flags,
233 S_IRUSR | S_IWUSR);
Sampa Misrad823cc02020-03-24 04:53:20 -0500234 }
235 if (fileFd == -1)
236 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600237 error(
238 "CertHandler::newFileAvailable:failed to open file for type {CERT_TYPE} ERROR={ERR}",
239 "CERT_TYPE", certType, "ERR", errno);
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 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600267 error(
268 "CertHandler::newFileAvailableWithMetaData:new file available client cert file, file handle: {FILE_HANDLE}",
269 "FILE_HANDLE", fileHandle);
Sridevi Rameshe3b3f632022-06-14 05:28:15 -0500270 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 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600276 error(
277 "newFileAvailableWithMetaData:client cert file Invalid data, file handle: {FILE_HANDLE}",
278 "FILE_HANDLE", fileHandle);
Sridevi Rameshe3b3f632022-06-14 05:28:15 -0500279 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 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600289 error(
290 "newFileAvailableWithMetaData:Failed to set status property of certicate entry, ERROR= {ERR_EXCEP}",
291 "ERR_EXCEP", e.what());
Sridevi Rameshe3b3f632022-06-14 05:28:15 -0500292 return PLDM_ERROR;
293 }
294 }
295 }
296 else if (certType == PLDM_FILE_TYPE_ROOT_CERT)
297 {
Patrick Williams6da4f912023-05-10 07:50:53 -0500298 fileFd = open((filePath + "RootCert").c_str(), flags,
299 S_IRUSR | S_IWUSR);
Sridevi Rameshe3b3f632022-06-14 05:28:15 -0500300 }
301 if (fileFd == -1)
302 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600303 error(
304 "newFileAvailableWithMetaData:failed to open file for type {CERT_TYPE} ERROR={ERR}",
305 "CERT_TYPE", certType, "ERR", errno);
Sridevi Rameshe3b3f632022-06-14 05:28:15 -0500306 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 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600337 error(
338 "CertHandler::fileAckWithMetaData:Failed to set status property of certicate entry, ERROR={ERR_EXCEP}",
339 "ERR_EXCEP", e.what());
Sridevi Rameshe3b3f632022-06-14 05:28:15 -0500340 return PLDM_ERROR;
341 }
342 }
343 return PLDM_SUCCESS;
344}
345
Sampa Misrad823cc02020-03-24 04:53:20 -0500346} // namespace responder
347} // namespace pldm