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