[ISSUE #268] expose ssl api to C (#501)

* [ISSUE #268] expose ssl api to C
diff --git a/include/CProducer.h b/include/CProducer.h
index 296b13f..e383793 100644
--- a/include/CProducer.h
+++ b/include/CProducer.h
@@ -63,7 +63,9 @@
 ROCKETMQCLIENT_API int SetProducerSendMsgTimeout(CProducer* producer, int timeout);
 ROCKETMQCLIENT_API int SetProducerCompressLevel(CProducer* producer, int level);
 ROCKETMQCLIENT_API int SetProducerMaxMessageSize(CProducer* producer, int size);
-ROCKETMQCLIENT_API int SetProducerMessageTrace(CProducer* consumer, CTraceModel openTrace);
+ROCKETMQCLIENT_API int SetProducerMessageTrace(CProducer* producer, CTraceModel openTrace);
+ROCKETMQCLIENT_API int SetProducerSsl(CProducer* producer, int enableSsl);
+ROCKETMQCLIENT_API int SetProducerSslPropertyFile(CProducer* producer, const char* sslPropertyFile);
 
 ROCKETMQCLIENT_API int SendMessageSync(CProducer* producer, CMessage* msg, CSendResult* result);
 ROCKETMQCLIENT_API int SendBatchMessage(CProducer* producer, CBatchMessage* msg, CSendResult* result);
diff --git a/include/CPullConsumer.h b/include/CPullConsumer.h
index 60a3367..4f5ba85 100644
--- a/include/CPullConsumer.h
+++ b/include/CPullConsumer.h
@@ -46,6 +46,8 @@
 ROCKETMQCLIENT_API int SetPullConsumerLogPath(CPullConsumer* consumer, const char* logPath);
 ROCKETMQCLIENT_API int SetPullConsumerLogFileNumAndSize(CPullConsumer* consumer, int fileNum, long fileSize);
 ROCKETMQCLIENT_API int SetPullConsumerLogLevel(CPullConsumer* consumer, CLogLevel level);
+ROCKETMQCLIENT_API int SetPullConsumerSsl(CPullConsumer* consumer, int enableSsl);
+ROCKETMQCLIENT_API int SetPullConsumerSslPropertyFile(CPullConsumer* consumer, const char* sslPropertyFile);
 
 ROCKETMQCLIENT_API int FetchSubscriptionMessageQueues(CPullConsumer* consumer,
                                                       const char* topic,
diff --git a/include/CPushConsumer.h b/include/CPushConsumer.h
index 5ed83f3..fd803c1 100644
--- a/include/CPushConsumer.h
+++ b/include/CPushConsumer.h
@@ -60,6 +60,8 @@
 ROCKETMQCLIENT_API int SetPushConsumerMaxCacheMessageSize(CPushConsumer* consumer, int maxCacheSize);
 ROCKETMQCLIENT_API int SetPushConsumerMaxCacheMessageSizeInMb(CPushConsumer* consumer, int maxCacheSizeInMb);
 ROCKETMQCLIENT_API int SetPushConsumerMessageTrace(CPushConsumer* consumer, CTraceModel openTrace);
+ROCKETMQCLIENT_API int SetPushConsumerSsl(CPushConsumer* consumer, int enableSsl);
+ROCKETMQCLIENT_API int SetPushConsumerSslPropertyFile(CPushConsumer* consumer, const char* sslPropertyFile);
 
 #ifdef __cplusplus
 }
diff --git a/include/TransactionMQProducer.h b/include/TransactionMQProducer.h
index 784de6c..7b9da77 100644
--- a/include/TransactionMQProducer.h
+++ b/include/TransactionMQProducer.h
@@ -81,6 +81,10 @@
   void setLogFileSizeAndNum(int fileNum, long perFileSize);  // perFileSize is MB unit
   void setMessageTrace(bool messageTrace);
   bool getMessageTrace() const;
+  void setEnableSsl(bool enableSsl);
+  bool getEnableSsl() const;
+  void setSslPropertyFile(const std::string& sslPropertyFile);
+  const std::string& getSslPropertyFile() const;
   std::shared_ptr<TransactionListener> getTransactionListener();
   void setTransactionListener(TransactionListener* listener);
   TransactionSendResult sendMessageInTransaction(MQMessage& msg, void* arg);
diff --git a/src/extern/CProducer.cpp b/src/extern/CProducer.cpp
index 7834f33..7b22cd1 100644
--- a/src/extern/CProducer.cpp
+++ b/src/extern/CProducer.cpp
@@ -816,6 +816,44 @@
   }
   return OK;
 }
+
+int SetProducerSsl(CProducer* producer, int enableSsl) {
+  if (producer == NULL) {
+    return NULL_POINTER;
+  }
+  DefaultProducer* defaultMQProducer = (DefaultProducer*)producer;
+  bool ssl = enableSsl != 0;
+  try {
+    if (CAPI_C_PRODUCER_TYPE_TRANSACTION == defaultMQProducer->producerType) {
+      defaultMQProducer->innerTransactionProducer->setEnableSsl(ssl);
+    } else {
+      defaultMQProducer->innerProducer->setEnableSsl(ssl);
+    }
+  } catch (exception& e) {
+    MQClientErrorContainer::setErr(string(e.what()));
+    return PRODUCER_START_FAILED;
+  }
+  return OK;
+}
+
+int SetProducerSslPropertyFile(CProducer* producer, const char* sslPropertyFile) {
+  if (producer == NULL) {
+    return NULL_POINTER;
+  }
+  DefaultProducer* defaultMQProducer = (DefaultProducer*)producer;
+  try {
+    if (CAPI_C_PRODUCER_TYPE_TRANSACTION == defaultMQProducer->producerType) {
+      defaultMQProducer->innerTransactionProducer->setSslPropertyFile(sslPropertyFile);
+    } else {
+      defaultMQProducer->innerProducer->setSslPropertyFile(sslPropertyFile);
+    }
+  } catch (exception& e) {
+    MQClientErrorContainer::setErr(string(e.what()));
+    return PRODUCER_START_FAILED;
+  }
+  return OK;
+}
+
 #ifdef __cplusplus
 };
 #endif
diff --git a/src/extern/CPullConsumer.cpp b/src/extern/CPullConsumer.cpp
index ddf39d0..9ea2671 100644
--- a/src/extern/CPullConsumer.cpp
+++ b/src/extern/CPullConsumer.cpp
@@ -135,6 +135,23 @@
   return OK;
 }
 
+int SetPullConsumerSsl(CPullConsumer* consumer, int enableSsl) {
+  if (consumer == NULL) {
+    return NULL_POINTER;
+  }
+  bool ssl = enableSsl != 0;
+  ((DefaultMQPullConsumer*)consumer)->setEnableSsl(ssl);
+  return OK;
+}
+
+int SetPullConsumerSslPropertyFile(CPullConsumer* consumer, const char* sslPropertyFile) {
+  if (consumer == NULL) {
+    return NULL_POINTER;
+  }
+  ((DefaultMQPullConsumer*)consumer)->setSslPropertyFile(sslPropertyFile);
+  return OK;
+}
+
 int FetchSubscriptionMessageQueues(CPullConsumer* consumer, const char* topic, CMessageQueue** mqs, int* size) {
   if (consumer == NULL) {
     return NULL_POINTER;
diff --git a/src/extern/CPushConsumer.cpp b/src/extern/CPushConsumer.cpp
index 9065804..431a567 100644
--- a/src/extern/CPushConsumer.cpp
+++ b/src/extern/CPushConsumer.cpp
@@ -306,6 +306,24 @@
   ((DefaultMQPushConsumer*)consumer)->setMessageTrace(messageTrace);
   return OK;
 }
+
+int SetPushConsumerSsl(CPushConsumer* consumer, int enableSsl) {
+  if (consumer == NULL) {
+    return NULL_POINTER;
+  }
+  bool ssl = enableSsl != 0;
+  ((DefaultMQPushConsumer*)consumer)->setEnableSsl(ssl);
+  return OK;
+}
+
+int SetPushConsumerSslPropertyFile(CPushConsumer* consumer, const char* sslPropertyFile) {
+  if (consumer == NULL) {
+    return NULL_POINTER;
+  }
+  ((DefaultMQPushConsumer*)consumer)->setSslPropertyFile(sslPropertyFile);
+  return OK;
+}
+
 #ifdef __cplusplus
 };
 #endif
diff --git a/src/producer/TransactionMQProducer.cpp b/src/producer/TransactionMQProducer.cpp
index 97ed1b3..61fcc20 100644
--- a/src/producer/TransactionMQProducer.cpp
+++ b/src/producer/TransactionMQProducer.cpp
@@ -166,6 +166,18 @@
 bool TransactionMQProducer::getMessageTrace() const {
   return impl->getMessageTrace();
 }
+void TransactionMQProducer::setEnableSsl(bool enableSsl) {
+  impl->setEnableSsl(enableSsl);
+}
+bool TransactionMQProducer::getEnableSsl() const {
+  return impl->getEnableSsl();
+}
+void TransactionMQProducer::setSslPropertyFile(const std::string& sslPropertyFile) {
+  impl->setSslPropertyFile(sslPropertyFile);
+}
+const std::string& TransactionMQProducer::getSslPropertyFile() const {
+  return impl->getSslPropertyFile();
+}
 std::shared_ptr<TransactionListener> TransactionMQProducer::getTransactionListener() {
   return impl->getTransactionListener();
 }
diff --git a/src/transport/EventLoop.cpp b/src/transport/EventLoop.cpp
index e66ceb5..7c6eee4 100644
--- a/src/transport/EventLoop.cpp
+++ b/src/transport/EventLoop.cpp
@@ -124,6 +124,7 @@
   std::string client_key_passwd = DEFAULT_CLIENT_KEY_PASSWD;
   std::string client_cert_file = DEFAULT_CLIENT_CERT_FILE;
   std::string ca_cert_file = DEFAULT_CA_CERT_FILE;
+  std::string verify = "true";
   auto properties = UtilAll::ReadProperties(ssl_property_file);
   if (!properties.empty()) {
     if (properties.find("tls.client.keyPath") != properties.end()) {
@@ -138,13 +139,22 @@
     if (properties.find("tls.client.trustCertPath") != properties.end()) {
       ca_cert_file = properties["tls.client.trustCertPath"];
     }
+    if (properties.find("tls.client.authServer") != properties.end()) {
+      verify = properties["tls.client.authServer"];
+      boost::algorithm::trim(verify);
+      boost::algorithm::to_lower(verify);
+    }
   } else {
     LOG_WARN(
         "The tls properties file is not specified or empty. "
         "Set it by modifying the api of setTlsPropertyFile and fill the configuration content.");
   }
 
-  SSL_CTX_set_verify(m_sslCtx.get(), SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, NULL);
+  if (verify == "false") {
+    SSL_CTX_set_verify(m_sslCtx.get(), SSL_VERIFY_NONE, NULL);
+  } else {
+    SSL_CTX_set_verify(m_sslCtx.get(), SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, NULL);
+  }
   SSL_CTX_set_mode(m_sslCtx.get(), SSL_MODE_AUTO_RETRY);
 
   if (client_key_passwd.empty()) {