Restore IPMI RMCP+ cipher suite commands

The work done to migrate this file from the old IPMI calling structure
to the new calling structure removed the RMCP+ cipher suite
commands. The prior commit was approved on the condition these
commands be restored.

Tested:
ipmitool raw 0xc 2 1 22 0 0 ; returns correct cipher count
ipmitool raw 0xc 2 1 23 0 0 ; returns the active cipher ID's

Change-Id: Ie0ac0fb066f53772174e7e61d2c81ae876b6c2e3
Signed-off-by: Johnathan Mantey <johnathanx.mantey@intel.com>
diff --git a/transporthandler.cpp b/transporthandler.cpp
index e88eb63..b48cbd0 100644
--- a/transporthandler.cpp
+++ b/transporthandler.cpp
@@ -1,3 +1,5 @@
+#include "app/channel.hpp"
+
 #include <arpa/inet.h>
 #include <netinet/ether.h>
 
@@ -6,6 +8,7 @@
 #include <cinttypes>
 #include <cstdint>
 #include <cstring>
+#include <fstream>
 #include <functional>
 #include <ipmid/api.hpp>
 #include <ipmid/message.hpp>
@@ -29,11 +32,6 @@
 #include <xyz/openbmc_project/Common/error.hpp>
 #include <xyz/openbmc_project/Network/IP/server.hpp>
 
-namespace ipmi
-{
-namespace transport
-{
-
 using phosphor::logging::commit;
 using phosphor::logging::elog;
 using phosphor::logging::entry;
@@ -42,6 +40,44 @@
 using sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure;
 using sdbusplus::xyz::openbmc_project::Network::server::IP;
 
+namespace cipher
+{
+
+std::vector<uint8_t> getCipherList()
+{
+    std::vector<uint8_t> cipherList;
+
+    std::ifstream jsonFile(cipher::configFile);
+    if (!jsonFile.is_open())
+    {
+        log<level::ERR>("Channel Cipher suites file not found");
+        elog<InternalFailure>();
+    }
+
+    auto data = Json::parse(jsonFile, nullptr, false);
+    if (data.is_discarded())
+    {
+        log<level::ERR>("Parsing channel cipher suites JSON failed");
+        elog<InternalFailure>();
+    }
+
+    // Byte 1 is reserved
+    cipherList.push_back(0x00);
+
+    for (const auto& record : data)
+    {
+        cipherList.push_back(record.value(cipher, 0));
+    }
+
+    return cipherList;
+}
+} // namespace cipher
+
+namespace ipmi
+{
+namespace transport
+{
+
 // LAN Handler specific response codes
 constexpr Cc ccParamNotSupported = 0x80;
 constexpr Cc ccParamSetLocked = 0x81;
@@ -1064,6 +1100,20 @@
         return responseInvalidFieldRequest();
     }
 
+    static std::vector<uint8_t> cipherList;
+    static bool listInit = false;
+    if (!listInit)
+    {
+        try
+        {
+            cipherList = cipher::getCipherList();
+            listInit = true;
+        }
+        catch (const std::exception& e)
+        {
+        }
+    }
+
     switch (static_cast<LanParam>(parameter))
     {
         case LanParam::SetStatus:
@@ -1158,8 +1208,23 @@
             return responseSuccess(std::move(ret));
         }
         case LanParam::CiphersuiteSupport:
+        {
+            if (!listInit)
+            {
+                return responseUnspecifiedError();
+            }
+            ret.pack(static_cast<uint8_t>(cipherList.size() - 1));
+            return responseSuccess(std::move(ret));
+        }
         case LanParam::CiphersuiteEntries:
-            return response(ccParamNotSupported);
+        {
+            if (!listInit)
+            {
+                return responseUnspecifiedError();
+            }
+            ret.pack(cipherList);
+            return responseSuccess(std::move(ret));
+        }
     }
 
     return response(ccParamNotSupported);