blob: 03f577acd5cc557d3ce4a165638524836af1801e [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{
18
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 {
30 std::cerr << "file for type " << certType << " doesn't exist\n";
31 return PLDM_ERROR;
32 }
33
34 auto fd = std::get<0>(it->second);
35 auto& remSize = std::get<1>(it->second);
36 auto rc = transferFileData(fd, false, offset, length, address);
37 if (rc == PLDM_SUCCESS)
38 {
39 remSize -= length;
40 if (!remSize)
41 {
42 close(fd);
43 certMap.erase(it);
44 }
45 }
46 return rc;
47}
48
49int CertHandler::readIntoMemory(uint32_t offset, uint32_t& length,
Sampa Misra69508502020-09-08 00:08:21 -050050 uint64_t address,
51 oem_platform::Handler* /*oemPlatformHandler*/)
Sampa Misrad823cc02020-03-24 04:53:20 -050052{
Varsha Kaverappa219ace92021-04-01 02:50:11 -050053 std::string filePath = certFilePath;
54 filePath += "CSR_" + std::to_string(fileHandle);
Sampa Misrad823cc02020-03-24 04:53:20 -050055 if (certType != PLDM_FILE_TYPE_CERT_SIGNING_REQUEST)
56 {
57 return PLDM_ERROR_INVALID_DATA;
58 }
Varsha Kaverappa219ace92021-04-01 02:50:11 -050059 auto rc = transferFileData(filePath.c_str(), true, offset, length, address);
60 fs::remove(filePath);
61 if (rc)
62 {
63 return PLDM_ERROR;
64 }
65 return PLDM_SUCCESS;
Sampa Misrad823cc02020-03-24 04:53:20 -050066}
67
Sampa Misra69508502020-09-08 00:08:21 -050068int CertHandler::read(uint32_t offset, uint32_t& length, Response& response,
69 oem_platform::Handler* /*oemPlatformHandler*/)
Sampa Misrad823cc02020-03-24 04:53:20 -050070{
Varsha Kaverappa219ace92021-04-01 02:50:11 -050071 std::string filePath = certFilePath;
72 filePath += "CSR_" + std::to_string(fileHandle);
Sampa Misrad823cc02020-03-24 04:53:20 -050073 if (certType != PLDM_FILE_TYPE_CERT_SIGNING_REQUEST)
74 {
75 return PLDM_ERROR_INVALID_DATA;
76 }
Varsha Kaverappa219ace92021-04-01 02:50:11 -050077 auto rc = readFile(filePath.c_str(), offset, length, response);
78 fs::remove(filePath);
79 if (rc)
80 {
81 return PLDM_ERROR;
82 }
83 return PLDM_SUCCESS;
Sampa Misrad823cc02020-03-24 04:53:20 -050084}
85
Sampa Misra69508502020-09-08 00:08:21 -050086int CertHandler::write(const char* buffer, uint32_t offset, uint32_t& length,
87 oem_platform::Handler* /*oemPlatformHandler*/)
Sampa Misrad823cc02020-03-24 04:53:20 -050088{
89 auto it = certMap.find(certType);
90 if (it == certMap.end())
91 {
92 std::cerr << "file for type " << certType << " doesn't exist\n";
93 return PLDM_ERROR;
94 }
95
96 auto fd = std::get<0>(it->second);
97 int rc = lseek(fd, offset, SEEK_SET);
98 if (rc == -1)
99 {
100 std::cerr << "lseek failed, ERROR=" << errno << ", OFFSET=" << offset
101 << "\n";
102 return PLDM_ERROR;
103 }
104 rc = ::write(fd, buffer, length);
105 if (rc == -1)
106 {
107 std::cerr << "file write failed, ERROR=" << errno
108 << ", LENGTH=" << length << ", OFFSET=" << offset << "\n";
109 return PLDM_ERROR;
110 }
111 length = rc;
112 auto& remSize = std::get<1>(it->second);
113 remSize -= length;
114 if (!remSize)
115 {
116 close(fd);
117 certMap.erase(it);
118 }
Varsha Kaverappa219ace92021-04-01 02:50:11 -0500119
120 if (certType == PLDM_FILE_TYPE_SIGNED_CERT)
121 {
122 constexpr auto certObjPath = "/xyz/openbmc_project/certs/ca/entry/";
123 constexpr auto certEntryIntf = "xyz.openbmc_project.Certs.Entry";
124
125 std::string filePath = certFilePath;
126 filePath += "ClientCert_" + std::to_string(fileHandle);
127
128 std::ifstream inFile;
129 inFile.open(filePath);
130 std::stringstream strStream;
131 strStream << inFile.rdbuf();
132 std::string str = strStream.str();
133 inFile.close();
134
135 if (!str.empty())
136 {
137 PropertyValue value{str};
138
139 DBusMapping dbusMapping{certObjPath + std::to_string(fileHandle),
140 certEntryIntf, "ClientCertificate",
141 "string"};
142 try
143 {
144 pldm::utils::DBusHandler().setDbusProperty(dbusMapping, value);
145 }
146 catch (const std::exception& e)
147 {
148 std::cerr << "failed to set Client certificate, "
149 "ERROR="
150 << e.what() << "\n";
151 return PLDM_ERROR;
152 }
153 PropertyValue valueStatus{
154 "xyz.openbmc_project.Certs.Entry.State.Complete"};
155 DBusMapping dbusMappingStatus{certObjPath +
156 std::to_string(fileHandle),
157 certEntryIntf, "Status", "string"};
158 try
159 {
160 pldm::utils::DBusHandler().setDbusProperty(dbusMappingStatus,
161 valueStatus);
162 }
163 catch (const std::exception& e)
164 {
165 std::cerr
166 << "failed to set status property of certicate entry, "
167 "ERROR="
168 << e.what() << "\n";
169 return PLDM_ERROR;
170 }
171 fs::remove(filePath);
172 }
173 else
174 {
175 PropertyValue value{"xyz.openbmc_project.Certs.Entry.State.BadCSR"};
176 DBusMapping dbusMapping{certObjPath + std::to_string(fileHandle),
177 certEntryIntf, "Status", "string"};
178 try
179 {
180 pldm::utils::DBusHandler().setDbusProperty(dbusMapping, value);
181 }
182 catch (const std::exception& e)
183 {
184 std::cerr
185 << "failed to set status property of certicate entry, "
186 "ERROR="
187 << e.what() << "\n";
188 return PLDM_ERROR;
189 }
190 }
191 }
Sampa Misrad823cc02020-03-24 04:53:20 -0500192 return PLDM_SUCCESS;
193}
194
195int CertHandler::newFileAvailable(uint64_t length)
196{
Varsha Kaverappa219ace92021-04-01 02:50:11 -0500197 fs::create_directories(certFilePath);
198 fs::permissions(certFilePath,
199 fs::perms::others_read | fs::perms::owner_write);
Sampa Misrad823cc02020-03-24 04:53:20 -0500200 int fileFd = -1;
201 int flags = O_WRONLY | O_CREAT | O_TRUNC;
Varsha Kaverappa219ace92021-04-01 02:50:11 -0500202 std::string filePath = certFilePath;
Sampa Misrad823cc02020-03-24 04:53:20 -0500203
204 if (certType == PLDM_FILE_TYPE_CERT_SIGNING_REQUEST)
205 {
206 return PLDM_ERROR_INVALID_DATA;
207 }
208 if (certType == PLDM_FILE_TYPE_SIGNED_CERT)
209 {
Varsha Kaverappa219ace92021-04-01 02:50:11 -0500210 fileFd = open(
211 (filePath + "ClientCert_" + std::to_string(fileHandle)).c_str(),
212 flags, S_IRUSR | S_IWUSR);
Sampa Misrad823cc02020-03-24 04:53:20 -0500213 }
214 else if (certType == PLDM_FILE_TYPE_ROOT_CERT)
215 {
Varsha Kaverappa219ace92021-04-01 02:50:11 -0500216 fileFd =
217 open((filePath + "RootCert").c_str(), flags, S_IRUSR | S_IWUSR);
Sampa Misrad823cc02020-03-24 04:53:20 -0500218 }
219 if (fileFd == -1)
220 {
221 std::cerr << "failed to open file for type " << certType
222 << " ERROR=" << errno << "\n";
223 return PLDM_ERROR;
224 }
225 certMap.emplace(certType, std::tuple(fileFd, length));
226 return PLDM_SUCCESS;
227}
228
229} // namespace responder
230} // namespace pldm