[VOL-3386] Add support for secure gRPC in openolt-agent

The init script of the openolt service may start with '--enable-tls <TLS_OPTION>' argument for the gRPC server.
Default is insecure with no '--enable-tls' argument.
The TLS capability depends upon the certificates stored at the keystore/ directory: 1. root.crt (CA public key), 2. server.crt (public key), 3.server.key (private key).
Four unit tests are added for the secure gRPC server which work with the keystore-test/ directory.
The certificates stored at the keystore-test/ directory are self-signed certificates, valid until Apr 11 23:16:58 2031 GMT.

Change-Id: I4d18a98a0193f501f922360c79f54b0fcedf14a5
diff --git a/agent/src/core_utils.cc b/agent/src/core_utils.cc
index 59c7cdc..0153078 100644
--- a/agent/src/core_utils.cc
+++ b/agent/src/core_utils.cc
@@ -14,8 +14,13 @@
  * limitations under the License.
  */
 
+#include <fstream>
+#include <sstream>
 #include "core_utils.h"
 
+// save the TLS option
+static std::string tls_option_arg{};
+
 std::string serial_number_to_str(bcmolt_serial_number* serial_number) {
 #define SERIAL_NUMBER_SIZE 12
     char buff[SERIAL_NUMBER_SIZE+1];
@@ -1673,3 +1678,48 @@
     }
     return false;
 }
+
+std::pair<grpc_ssl_client_certificate_request_type, bool> get_grpc_tls_option(const char* tls_option) {
+    static std::map<std::string,grpc_ssl_client_certificate_request_type> grpc_security_option_map = {{"GRPC_SSL_DONT_REQUEST_CLIENT_CERTIFICATE",
+                                                                                                        grpc_ssl_client_certificate_request_type::GRPC_SSL_DONT_REQUEST_CLIENT_CERTIFICATE},
+                                                                                                      {"GRPC_SSL_REQUEST_CLIENT_CERTIFICATE_BUT_DONT_VERIFY",
+                                                                                                        grpc_ssl_client_certificate_request_type::GRPC_SSL_REQUEST_CLIENT_CERTIFICATE_BUT_DONT_VERIFY},
+                                                                                                      {"GRPC_SSL_REQUEST_CLIENT_CERTIFICATE_AND_VERIFY",
+                                                                                                        grpc_ssl_client_certificate_request_type::GRPC_SSL_REQUEST_CLIENT_CERTIFICATE_AND_VERIFY},
+                                                                                                      {"GRPC_SSL_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_BUT_DONT_VERIFY",
+                                                                                                        grpc_ssl_client_certificate_request_type::GRPC_SSL_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_BUT_DONT_VERIFY},
+                                                                                                      {"GRPC_SSL_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY",
+                                                                                                        grpc_ssl_client_certificate_request_type::GRPC_SSL_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY}};
+
+    auto it = grpc_security_option_map.find(tls_option);
+    if (it == grpc_security_option_map.end()) {
+        OPENOLT_LOG(ERROR, openolt_log_id, "invalid gRPC Server security option: %s\n", tls_option);
+        return {grpc_ssl_client_certificate_request_type::GRPC_SSL_DONT_REQUEST_CLIENT_CERTIFICATE, false};
+    } else {
+        OPENOLT_LOG(INFO, openolt_log_id, "valid gRPC Server security option: %s\n", tls_option);
+        tls_option_arg = std::string{tls_option};
+        return {it->second, true};
+    }
+}
+
+const std::string &get_grpc_tls_option() {
+    return tls_option_arg;
+}
+
+bool is_grpc_secure() {
+    return !tls_option_arg.empty();
+}
+
+std::pair<std::string, bool> read_from_txt_file(const std::string& file_name) {
+    std::ifstream in_file(file_name);
+
+    if (!in_file.is_open()) {
+        OPENOLT_LOG(ERROR, openolt_log_id, "error opening file '%s'\n", file_name.c_str());
+        return {"", false};
+    }
+
+    std::stringstream buffer;
+    buffer << in_file.rdbuf();
+
+    return {buffer.str(), in_file.good()};
+}