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