[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/test/keystore-test/root.crt b/agent/test/keystore-test/root.crt
new file mode 100644
index 0000000..2ae357b
--- /dev/null
+++ b/agent/test/keystore-test/root.crt
@@ -0,0 +1,24 @@
+-----BEGIN CERTIFICATE-----
+MIIEDTCCAvWgAwIBAgIJALTkUm+wi0Y9MA0GCSqGSIb3DQEBCwUAMIGcMQswCQYD
+VQQGEwJUUjERMA8GA1UECAwISXN0YW5idWwxETAPBgNVBAcMCElzdGFuYnVsMQ8w
+DQYDVQQKDAZBUkdFTEExDTALBgNVBAsMBFNFQkExGzAZBgNVBAMMEnNlYmEuYXJn
+ZWxhLmNvbS50cjEqMCgGCSqGSIb3DQEJARYbbmV0c2lhLmRldm9wc0BhcmdlbGEu
+Y29tLnRyMB4XDTIxMDQxMzIzMTY1OFoXDTMxMDQxMTIzMTY1OFowgZwxCzAJBgNV
+BAYTAlRSMREwDwYDVQQIDAhJc3RhbmJ1bDERMA8GA1UEBwwISXN0YW5idWwxDzAN
+BgNVBAoMBkFSR0VMQTENMAsGA1UECwwEU0VCQTEbMBkGA1UEAwwSc2ViYS5hcmdl
+bGEuY29tLnRyMSowKAYJKoZIhvcNAQkBFhtuZXRzaWEuZGV2b3BzQGFyZ2VsYS5j
+b20udHIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCwos2j7GWNExJZ
+PgeOURaP/9JcV+1SC5aDqG4UwLlAGSPoQUkf/0LjgMde9ZeRe8rugGXW39v2cbWm
+eb5TNyTwWGED2wEMVijzBgnYTYA6nXTxz+XAvxVu/x6fHtNMOqHGiewN0S1eY7bz
+rE1zq6SeunDJGCW6pIa4aNMq7/ngDsPrSc6f1pKZpCgrNSW/LnGdgTB2HkaroUr8
+vy3OWZ0FG042HjT7q+MjEgqGLDl7VkBFrJn2gp4sfgX1WSM/9brhcaVZ/puagaY8
+Ju2Dq3foXDW3xgW9y22mk/3cQpRGRSad9+ZAWb9ZPyp5lcUaqpMuYyiFoGctdQT8
+s1LMbPCnAgMBAAGjUDBOMB0GA1UdDgQWBBTpfNEjdHBqnzSDYXuwrFCnZ7P1/zAf
+BgNVHSMEGDAWgBTpfNEjdHBqnzSDYXuwrFCnZ7P1/zAMBgNVHRMEBTADAQH/MA0G
+CSqGSIb3DQEBCwUAA4IBAQBorTfS9g2xi9kO42nDTs+VRv64j09cJyZl5BFoivFO
+SV2O64ubp6YEaKjqUnPuzs7D3j8cjalqeIeD2tFJHRrv8XADlgivEtTk2o5sCEJx
+66eOAXeqlLPHK9dt3IxKI5kPBTGKQHw2uNG8VOsRlq2DB798ueWxzUWPpxjhSFL/
+YP/o3pEWxit5SirBAoaRZaccjPHz2c/4IfGuoPOXun+qKvt/ic2QRm23e62Wb/Do
+eugVy1Zi0aAOenoJaNuiZEX7l2qZ4RssGheJxWdEOzGZ9YxpS7WseKgxufQ9RmoR
+4J4bU/hVy2su6+cqn7Q5YchcJjfuT181yq+/UFgpvMTa
+-----END CERTIFICATE-----
diff --git a/agent/test/keystore-test/server.crt b/agent/test/keystore-test/server.crt
new file mode 100644
index 0000000..8186f31
--- /dev/null
+++ b/agent/test/keystore-test/server.crt
@@ -0,0 +1,23 @@
+-----BEGIN CERTIFICATE-----
+MIIDzTCCArWgAwIBAgIJAILLZCQ2zGU7MA0GCSqGSIb3DQEBCwUAMIGcMQswCQYD
+VQQGEwJUUjERMA8GA1UECAwISXN0YW5idWwxETAPBgNVBAcMCElzdGFuYnVsMQ8w
+DQYDVQQKDAZBUkdFTEExDTALBgNVBAsMBFNFQkExGzAZBgNVBAMMEnNlYmEuYXJn
+ZWxhLmNvbS50cjEqMCgGCSqGSIb3DQEJARYbbmV0c2lhLmRldm9wc0BhcmdlbGEu
+Y29tLnRyMB4XDTIxMDQxMzIzMTcyNFoXDTMxMDQxMTIzMTcyNFowUTELMAkGA1UE
+BhMCQ0ExDTALBgNVBAgMBE5vbmUxCzAJBgNVBAcMAk5CMQ0wCwYDVQQKDAROb25l
+MRcwFQYDVQQDDA4xOTIuMTY4LjMwLjIyMTCCASIwDQYJKoZIhvcNAQEBBQADggEP
+ADCCAQoCggEBANh3OVBIS7kFcOda1dA8+423RRhfrwsL3AHjthZ6+f9TYSb0BcFv
+VQKwGRWXVFZsX3q6yivi8zq1AoLUYd7Ir0W+UFuP17unMeKij3PjPMwc42aL5lfs
+7b1VVG1yk4CoMHdGs/gpbLQwAvhwvaovI1SReCW8ddehJ6P50P8ACVmklK08W9Hm
+mdzAdq/HUw/oaCi5kNtFP2aqXlOofYaJ6aYRLaGYNpgvj9SiGo62SB0VRteik4Pd
+HjjiTkWUcEblUC89UfQCcqGUG4vXoNhaS2AmMCg+MgPlaWRyUT6q9uXQ5CnLSD9r
+lDcSNsHHwapMf1lWPBPB2r0EkQpbazD+WWsCAwEAAaNcMFowHwYDVR0jBBgwFoAU
+6XzRI3Rwap80g2F7sKxQp2ez9f8wCQYDVR0TBAIwADALBgNVHQ8EBAMCBPAwHwYD
+VR0RBBgwFoIOMTkyLjE2OC4zMC4yMjGHBMCoHt0wDQYJKoZIhvcNAQELBQADggEB
+AIHUdvm/njSX5wQzegQeq7Axo+o6HfhJFH5ot1B0rtLG3/SkWOj+t9gqEeJxLYCI
+Wz+EhUupISZ/Vb8KtSZgLPFQ+H61+x945zT0zE61Wh3hKJOK1HZVbMhtWHbzaqEa
+nPQniw9wCKflnUgJUqYGb3rBFqmCEKYXvcyQp63zUmnAIJze+liEXVmHpCPPR+Jo
+CcoSXMR7iCl6s1hpkSB72CxhvcZi6zfCkyVTmxDfwVTtciqjQEr8gC2ufff7qRHM
+ZRrU9NtiMQqu5yZQsQiFGMDU68sHYz3uQQSjaqih+DcPLf7Pg1qFrrbbq7C0Znmw
+rCp11vZTwWKj3fg/lR7AAq4=
+-----END CERTIFICATE-----
diff --git a/agent/test/keystore-test/server.key b/agent/test/keystore-test/server.key
new file mode 100644
index 0000000..371ceeb
--- /dev/null
+++ b/agent/test/keystore-test/server.key
@@ -0,0 +1,28 @@
+-----BEGIN PRIVATE KEY-----
+MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDYdzlQSEu5BXDn
+WtXQPPuNt0UYX68LC9wB47YWevn/U2Em9AXBb1UCsBkVl1RWbF96usor4vM6tQKC
+1GHeyK9FvlBbj9e7pzHioo9z4zzMHONmi+ZX7O29VVRtcpOAqDB3RrP4KWy0MAL4
+cL2qLyNUkXglvHXXoSej+dD/AAlZpJStPFvR5pncwHavx1MP6GgouZDbRT9mql5T
+qH2GiemmES2hmDaYL4/UohqOtkgdFUbXopOD3R444k5FlHBG5VAvPVH0AnKhlBuL
+16DYWktgJjAoPjID5WlkclE+qvbl0OQpy0g/a5Q3EjbBx8GqTH9ZVjwTwdq9BJEK
+W2sw/llrAgMBAAECggEAJPrZM7nmFcm0LBH8jQKeBuvURgGyqbRw9XGtXdHMe64G
+3ty5Tv5yC2+CGYoswkbpWNIoT68J1nGt6CPYRHMMXmHQ4JOGS2yYvRsAXs/nRwd4
+YcBsrYCwbLPzJG96e3RAM2BExpRtGatKFp9MB5Ld+kiPugKkLx4842p+JdIfxsxi
+lggzGkneu95yJnTS2i/BcKUAVO2HM1DKOtfgIofPCT4tgZpboa0p7GKa1TtqqdTT
+Zk4t6qVh3MSRYcQe2pMXZJgOAJupAzXIAYoafw+io22dt2mDqLhb9YRxCIabhYif
+Oz8e4b9O8hvJcTs0/2hYUW4vtDQzlFCeSaC5fuk5oQKBgQDw04BnrkQ84kPZ0PrN
+e8zWk2jAqBmiyzgykMbUnX34CImINTjwgqhgKjMFepqxGwsQN7YHyu5Jq7I1sEYm
+LSrQGDa8zqTifcSkyHq7k+TFM371/OCW+xAUITrzd/KZdBiH2syAePHUO/02G7up
+aIUjvaB2Qp/qVPe3MzDkVGvDNQKBgQDmGsp4VdL/SEsWCSs+5tIK2gnok2+/V9s5
+fSPPROABsEBtLf+rJeGmh6qkOBeRZnncAajza6oKMKo9NLA68qFNs7Yg+ZvnDcu7
+X+VyRiXp+uR65oNPEhIMO8x7NGPx+VqYZtAWI0I3lGZpzkZ8zfVHFJCFpd+ieDv8
+RSAHX3ueHwKBgGjSxrtaYR1XJ01x5xj14A0uEJR7Ft2DMyzfU4xMGP6TSLne4K/f
+T0a8V4T0/sxEBybB+RufOuUaNPGljoMjedUmFP1NvPtQ3v0SvklTcGpdpc+QiHlv
+QmpgpHZBKXmdzOelVwo8mpZUnjylCaQNeJY7/dI74btvzHsTbx6TmGxZAoGBAOER
+3W8cy3hl1wPjzggFr/drU/vIkqo/HjA6Jherj8w3AJ2KO6TFNdU0qAVe1DalXJaE
+jSQj8DttZGbfrWzLPFmLaZ8RZ5v104wgfYZr9NPLU0afSFrEGyEaMKVmFkhtlV6y
+WeD9ddx1bEMbv7h9n+d5xu7i0z7QiiPz3SM5EuoTAoGBAJKBvQx7ZtW2QMgdwxdF
+2Yfv7qmifUcsi7vLNeEQGSBa6s7SXPLrUaODSIKL0lIgIsxQelxJj8zfDkqVEWqO
+8b0g+v9FAqQjgB90mALPNcdS/DCuQ2Vdx0ertkGjUetWaAhuHspZi79IOG+2j9iv
+pvZKgzwl2RaJTlr77Qz6lsa4
+-----END PRIVATE KEY-----
diff --git a/agent/test/src/test_core.cc b/agent/test/src/test_core.cc
index bce275e..55297b9 100644
--- a/agent/test/src/test_core.cc
+++ b/agent/test/src/test_core.cc
@@ -18,6 +18,7 @@
 #include "bal_mocker.h"
 #include "core.h"
 #include "core_data.h"
+#include "server.h"
 #include <future>
 using namespace testing;
 using namespace std;
@@ -3239,3 +3240,87 @@
     Status status = GetLogicalOnuDistance_(pon_ni, onu_id, onu_logical_distance);
     ASSERT_TRUE( status.error_message() != Status::OK.error_message() );
 }
+
+////////////////////////////////////////////////////////////////////////////
+// For testing Secure Server functionality
+////////////////////////////////////////////////////////////////////////////
+
+class TestSecureServer : public Test {
+    protected:
+        virtual void SetUp() {}
+        virtual void TearDown() {}
+};
+
+TEST_F(TestSecureServer, StartInsecureServer) {
+    // const to prevent the following warning:
+    // warning: deprecated conversion from string constant to 'char*' [-Wwrite-strings]
+    const char *args[] = {"./openolt"};
+    int argc = sizeof(args) / sizeof(args[0]);
+    char **argv = const_cast<char**>(args);
+
+    bool ok = RunServer(argc, argv);
+
+    ASSERT_TRUE(ok);
+
+    OPENOLT_LOG(INFO, openolt_log_id, "insecure gRPC server has been started and shut down successfully\n");
+}
+
+TEST_F(TestSecureServer, StartWithInvalidTLSOption) {
+    const char *args[] = {"./openolt", "--enable-tls", "DUMMY_GRPC_SSL_DONT_REQUEST_CLIENT_CERTIFICATE"};
+    int argc = sizeof(args) / sizeof(args[0]);
+    char **argv = const_cast<char**>(args);
+
+    bool ok = RunServer(argc, argv);
+
+    ASSERT_FALSE(ok);
+
+    OPENOLT_LOG(INFO, openolt_log_id, "secure gRPC server could not be started due to invalid TLS option\n");
+}
+
+TEST_F(TestSecureServer, CertificatesAreMissing) {
+    const char *args[] = {"./openolt", "--enable-tls", "GRPC_SSL_DONT_REQUEST_CLIENT_CERTIFICATE"};
+    int argc = sizeof(args) / sizeof(args[0]);
+    char **argv = const_cast<char**>(args);
+    const std::string cmd = "exec [ -d './keystore' ] && rm -rf './keystore'";
+
+    int res = std::system(cmd.c_str());
+    if (res == 0) {
+        std::cout << "directory ./keystore is deleted\n";
+    } else {
+        std::cout << "directory ./keystore is not existing\n";
+    }
+
+    bool ok = RunServer(argc, argv);
+
+    ASSERT_FALSE(ok);
+
+    OPENOLT_LOG(INFO, openolt_log_id, "secure gRPC server could not be started due to missing certificates\n");
+}
+
+TEST_F(TestSecureServer, StartWithValidTLSOption) {
+    const char *args[] = {"./openolt", "--enable-tls", "GRPC_SSL_DONT_REQUEST_CLIENT_CERTIFICATE"};
+    int argc = sizeof(args) / sizeof(args[0]);
+    char **argv = const_cast<char**>(args);
+    const std::string cmd_1 = "exec cp -r ./keystore-test ./keystore";
+    const std::string cmd_2 = "exec rm -rf './keystore'";
+
+    int res = std::system(cmd_1.c_str());
+    if (res == 0) {
+        std::cout << "directory ./keystore is copied from ./keystore-test\n";
+
+        bool ok = RunServer(argc, argv);
+        ASSERT_TRUE(ok);
+
+        OPENOLT_LOG(INFO, openolt_log_id, "secure gRPC server has been started with the given certificates and TLS options, and shut down successfully\n");
+
+        res = std::system(cmd_2.c_str());
+        if (res == 0) {
+            std::cout << "directory ./keystore is deleted\n";
+        } else {
+            std::cerr << "directory ./keystore could not be deleted\n";
+        }
+    } else {
+        std::cerr << "directory ./keystore could not be prepared, err: " << res << '\n';
+        FAIL();
+    }
+}