1 #include "file_io_type_cert.hpp"
2 
3 #include "libpldm/base.h"
4 #include "oem/ibm/libpldm/file_io.h"
5 
6 #include "common/utils.hpp"
7 
8 #include <stdint.h>
9 
10 #include <iostream>
11 
12 namespace pldm
13 {
14 namespace responder
15 {
16 
17 static constexpr auto csrFilePath = "/var/lib/bmcweb/CSR";
18 static constexpr auto rootCertPath = "/var/lib/bmcweb/RootCert";
19 static constexpr auto clientCertPath = "/var/lib/bmcweb/ClientCert";
20 
21 CertMap CertHandler::certMap;
22 
23 int CertHandler::writeFromMemory(uint32_t offset, uint32_t length,
24                                  uint64_t address)
25 {
26     auto it = certMap.find(certType);
27     if (it == certMap.end())
28     {
29         std::cerr << "file for type " << certType << " doesn't exist\n";
30         return PLDM_ERROR;
31     }
32 
33     auto fd = std::get<0>(it->second);
34     auto& remSize = std::get<1>(it->second);
35     auto rc = transferFileData(fd, false, offset, length, address);
36     if (rc == PLDM_SUCCESS)
37     {
38         remSize -= length;
39         if (!remSize)
40         {
41             close(fd);
42             certMap.erase(it);
43         }
44     }
45     return rc;
46 }
47 
48 int CertHandler::readIntoMemory(uint32_t offset, uint32_t& length,
49                                 uint64_t address)
50 {
51     if (certType != PLDM_FILE_TYPE_CERT_SIGNING_REQUEST)
52     {
53         return PLDM_ERROR_INVALID_DATA;
54     }
55     return transferFileData(csrFilePath, true, offset, length, address);
56 }
57 
58 int CertHandler::read(uint32_t offset, uint32_t& length, Response& response)
59 {
60     if (certType != PLDM_FILE_TYPE_CERT_SIGNING_REQUEST)
61     {
62         return PLDM_ERROR_INVALID_DATA;
63     }
64     return readFile(csrFilePath, offset, length, response);
65 }
66 
67 int CertHandler::write(const char* buffer, uint32_t offset, uint32_t& length)
68 {
69     auto it = certMap.find(certType);
70     if (it == certMap.end())
71     {
72         std::cerr << "file for type " << certType << " doesn't exist\n";
73         return PLDM_ERROR;
74     }
75 
76     auto fd = std::get<0>(it->second);
77     int rc = lseek(fd, offset, SEEK_SET);
78     if (rc == -1)
79     {
80         std::cerr << "lseek failed, ERROR=" << errno << ", OFFSET=" << offset
81                   << "\n";
82         return PLDM_ERROR;
83     }
84     rc = ::write(fd, buffer, length);
85     if (rc == -1)
86     {
87         std::cerr << "file write failed, ERROR=" << errno
88                   << ", LENGTH=" << length << ", OFFSET=" << offset << "\n";
89         return PLDM_ERROR;
90     }
91     length = rc;
92     auto& remSize = std::get<1>(it->second);
93     remSize -= length;
94     if (!remSize)
95     {
96         close(fd);
97         certMap.erase(it);
98     }
99     return PLDM_SUCCESS;
100 }
101 
102 int CertHandler::newFileAvailable(uint64_t length)
103 {
104     static constexpr auto vmiCertPath = "/var/lib/bmcweb";
105     fs::create_directories(vmiCertPath);
106     int fileFd = -1;
107     int flags = O_WRONLY | O_CREAT | O_TRUNC;
108 
109     if (certType == PLDM_FILE_TYPE_CERT_SIGNING_REQUEST)
110     {
111         return PLDM_ERROR_INVALID_DATA;
112     }
113     if (certType == PLDM_FILE_TYPE_SIGNED_CERT)
114     {
115         fileFd = open(clientCertPath, flags);
116     }
117     else if (certType == PLDM_FILE_TYPE_ROOT_CERT)
118     {
119         fileFd = open(rootCertPath, flags);
120     }
121     if (fileFd == -1)
122     {
123         std::cerr << "failed to open file for type " << certType
124                   << " ERROR=" << errno << "\n";
125         return PLDM_ERROR;
126     }
127     certMap.emplace(certType, std::tuple(fileFd, length));
128     return PLDM_SUCCESS;
129 }
130 
131 } // namespace responder
132 } // namespace pldm
133