Index: trunk/BNC/src/bncmain.cpp
===================================================================
--- trunk/BNC/src/bncmain.cpp	(revision 9790)
+++ trunk/BNC/src/bncmain.cpp	(revision 9795)
@@ -95,8 +95,9 @@
       "\n"
       "Network Panel keys:\n"
-      "   proxyHost       {Proxy host, name or IP address [character string]}\n"
-      "   proxyPort       {Proxy port [integer number]}\n"
-      "   sslCaCertPath   {Full path to SSL certificates [character string]}\n"
-      "   sslIgnoreErrors {Ignore SSL authorization errors [integer number: 0=no,2=yes]}\n"
+      "   proxyHost         {Proxy host, name or IP address [character string]}\n"
+      "   proxyPort         {Proxy port [integer number]}\n"
+      "   sslCaCertPath     {Full path to SSL certificates [character string]}\n"
+      "   sslClientCertPath {Full path to client SSL certificates [character string]}\n"      
+      "   sslIgnoreErrors   {Ignore SSL authorization errors [integer number: 0=no,2=yes]}\n"
       "\n"
       "General Panel keys:\n"
Index: trunk/BNC/src/bncnetqueryv2.cpp
===================================================================
--- trunk/BNC/src/bncnetqueryv2.cpp	(revision 9790)
+++ trunk/BNC/src/bncnetqueryv2.cpp	(revision 9795)
@@ -36,11 +36,17 @@
 
   bncSettings settings;
-  _sslIgnoreErrors =
-     (Qt::CheckState(settings.value("sslIgnoreErrors").toInt()) == Qt::Checked);
-
-  if (_secure && !QSslSocket::supportsSsl()) {
-    BNC_CORE->slotMessage("No SSL support, install OpenSSL run-time libraries", true);
-    stop();
-  }
+  _sslIgnoreErrors = (Qt::CheckState(settings.value("sslIgnoreErrors").toInt()) == Qt::Checked);
+
+  if (_secure ) {
+    if (!QSslSocket::supportsSsl()) {
+      BNC_CORE->slotMessage("No SSL support, install OpenSSL run-time libraries", true);
+      stop();
+    }
+    // Generate filenames to consider a potential client certificate
+    _crtFileName = settings.value("sslClientCertPath").toString() + _url.host() + QString(".%1.crt").arg(_url.port());
+    _keyFileName = settings.value("sslClientCertPath").toString() + _url.host() + QString(".%1.key").arg(_url.port());
+  }
+
+
 }
 
@@ -122,4 +128,5 @@
   if (_url.scheme().isEmpty()) {
     if (_secure) {
+      _url.setPort(443);
       _url.setScheme("https");
     }
@@ -134,6 +141,23 @@
   // Network Request
   // ---------------
+  bncSslConfig sslConfig = BNC_SSL_CONFIG;
+
+  if (_secure) {
+    QFile clientCrtFile(_crtFileName);
+    QFile privateKeyFile(_keyFileName);
+    if ( clientCrtFile.exists() && privateKeyFile.exists()) {
+      // set local certificate if available
+      clientCrtFile.open(QIODevice::ReadOnly);
+      QSslCertificate clientCrt(&clientCrtFile);
+      sslConfig.setLocalCertificate(clientCrt);
+      // set private key if available
+      privateKeyFile.open(QIODevice::ReadOnly);
+      QSslKey privateKey(&privateKeyFile, QSsl::Rsa);
+      sslConfig.setPrivateKey(privateKey);
+    }
+  }
+
   QNetworkRequest request;
-  request.setSslConfiguration(BNC_SSL_CONFIG);
+  request.setSslConfiguration(sslConfig);
   request.setUrl(_url);
   request.setRawHeader("Host"         , _url.host().toLatin1());
Index: trunk/BNC/src/bncnetqueryv2.h
===================================================================
--- trunk/BNC/src/bncnetqueryv2.h	(revision 9790)
+++ trunk/BNC/src/bncnetqueryv2.h	(revision 9795)
@@ -7,4 +7,5 @@
 #include <QNetworkReply>
 #include <QSslError>
+#include <QSslKey>
 
 #include "bncnetquery.h"
@@ -33,4 +34,6 @@
   QNetworkAccessManager* _manager;
   QNetworkReply*         _reply;
+  QString                _crtFileName;
+  QString                _keyFileName;
   QEventLoop*            _eventLoop;
   bool                   _firstData;
Index: trunk/BNC/src/bncsettings.cpp
===================================================================
--- trunk/BNC/src/bncsettings.cpp	(revision 9790)
+++ trunk/BNC/src/bncsettings.cpp	(revision 9795)
@@ -76,4 +76,5 @@
     setValue_p("proxyPort",           "");
     setValue_p("sslCaCertPath",       "");
+    setValue_p("sslClientCertPath",   "");
     setValue_p("sslIgnoreErrors",    "0");
     // General
Index: trunk/BNC/src/bncsslconfig.cpp
===================================================================
--- trunk/BNC/src/bncsslconfig.cpp	(revision 9790)
+++ trunk/BNC/src/bncsslconfig.cpp	(revision 9795)
@@ -35,6 +35,5 @@
 ////////////////////////////////////////////////////////////////////////////
 bncSslConfig::bncSslConfig() :
-  QSslConfiguration(QSslConfiguration::defaultConfiguration())
-{
+  QSslConfiguration(QSslConfiguration::defaultConfiguration()) {
 
   bncSettings settings;
@@ -46,8 +45,4 @@
   QList<QSslCertificate> caCerts = this->caCertificates();
 
-  // Bug in Qt: the wildcard does not work here:
-  // -------------------------------------------
-  // caCerts += QSslCertificate::fromPath(dirName + QDir::separator() + "*crt",
-  //                                      QSsl::Pem, QRegExp::Wildcard);
   QDir dir(dirName);
   QStringList nameFilters;
@@ -62,4 +57,6 @@
 
   this->setCaCertificates(caCerts);
+
+
 }
 
Index: trunk/BNC/src/bncwindow.cpp
===================================================================
--- trunk/BNC/src/bncwindow.cpp	(revision 9790)
+++ trunk/BNC/src/bncwindow.cpp	(revision 9795)
@@ -195,6 +195,7 @@
           this, SLOT(slotBncTextChanged()));
 
-  _sslCaCertPathLineEdit   = new QLineEdit(settings.value("sslCaCertPath").toString());
-  _sslIgnoreErrorsCheckBox = new QCheckBox();
+  _sslCaCertPathLineEdit     = new QLineEdit(settings.value("sslCaCertPath").toString());
+  _sslClientCertPathLineEdit = new QLineEdit(settings.value("sslClientCertPath").toString());
+  _sslIgnoreErrorsCheckBox   = new QCheckBox();
   _sslIgnoreErrorsCheckBox->setCheckState(Qt::CheckState(
                                           settings.value("sslIgnoreErrors").toInt()));
@@ -762,7 +763,9 @@
   pLayout->addWidget(_sslCaCertPathLineEdit,                                 3, 1, 1,10);
   pLayout->addWidget(new QLabel("Default:  " + bncSslConfig::defaultPath()), 3,11, 1,20);
-  pLayout->addWidget(new QLabel("Ignore SSL authorization errors"),          4, 0);
-  pLayout->addWidget(_sslIgnoreErrorsCheckBox,                               4, 1, 1,10);
-  pLayout->addWidget(new QLabel(""),                                         5, 1);
+  pLayout->addWidget(new QLabel("Path to SSL client certificates"),          4, 0);
+  pLayout->addWidget(_sslClientCertPathLineEdit,                             4, 1, 1,10);
+  pLayout->addWidget(new QLabel("Ignore SSL authorization errors"),          5, 0);
+  pLayout->addWidget(_sslIgnoreErrorsCheckBox,                               5, 1, 1,10);
+  pLayout->addWidget(new QLabel(""),                                         6, 1);
   pLayout->setRowStretch(6, 999);
 
@@ -1370,5 +1373,6 @@
   _proxyHostLineEdit->setWhatsThis(tr("<p>If you are running BNC within a protected Local Area Network (LAN), you may need to use a proxy server to access the Internet. Enter your proxy server IP and port number in case one is operated in front of BNC. If you do not know the IP and port of your proxy server, check the proxy server settings in your Internet browser or ask your network administrator. Without any entry, BNC will try to use the system proxies. </p><p>Note that IP streaming is sometimes not allowed in a LAN. In this case you need to ask your network administrator for an appropriate modification of the local security policy or for the installation of a TCP relay to the Ntrip Broadcasters. If this is not possible, you may need to run BNC outside your LAN on a network that has unobstructed connection to the Internet. <i>[key: proxyHost]</i></p>"));
   _proxyPortLineEdit->setWhatsThis(tr("<p>Enter your proxy server port number in case a proxy is operated in front of BNC. <i>[key: proxyPort]</i></p>"));
-  _sslCaCertPathLineEdit->setWhatsThis(tr("<p>Communication with an Ntrip Broadcaster over SSL requires the exchange of client and/or server certificates. Specify the path to a directory where you save certificates on your system. Don't try communication via SSL if you are not sure whether this is supported by the involved Ntrip Broadcaster.</p><p>Note that SSL communication is usually done over port 443. <i>[key: sslCaCertPath]</i></p>"));
+  _sslCaCertPathLineEdit->setWhatsThis(tr("<p>Communication with an Ntrip Broadcaster over SSL requires the exchange of server certificates. Specify the path to a directory where you save CA certificates on your system. </p><p>BNC creates from *.crt and *.pem files a CA certificate database, which is used by the socket during the handshake phase to validate the peer's certificate. </p><p>Don't try communication via SSL if you are not sure whether this is supported by the involved Ntrip Broadcaster.</p><p>Note that SSL communication is usually done over port 443. <i>[key: sslCaCertPath]</i></p>"));
+  _sslClientCertPathLineEdit->setWhatsThis(tr("<p>Two-sided communication with an Ntrip Broadcaster over SSL requires in addition the exchange of client certificates. Specify the full path to the client certificates on your system.</p><p></p><p>The file naming convention for client certificates in BNC is as follows: &lt;hostname&gt;.&lt;port&gt;.crt for the certificate and &lt;hostname&gt;.&lt;port&gt;.key for the private key, where &lt;hostname&gt; is without https://. </p><p> If available, the client or personal authentication certificate is presented to the peer during the SSL handshake process. Password protected key files are not supported. </p><p>Don't try communication via two sided SSL if you are not sure whether this is supported by the involved Ntrip Broadcaster. </p><p>Note that SSL communication is usually done over port 443. <i>[key: sslClientCertPath]</i></p>"));
   _sslIgnoreErrorsCheckBox->setWhatsThis(tr("<p>SSL communication may involve queries coming from the Ntrip Broadcaster. Tick 'Ignore SSL authorization errors' if you don't want to be bothered with this. <i>[key: sslIgnoreErrors]</i></p>"));
 
@@ -1593,4 +1597,5 @@
   delete _proxyPortLineEdit;
   delete _sslCaCertPathLineEdit;
+  delete _sslClientCertPathLineEdit;
   delete _sslIgnoreErrorsCheckBox;
   delete _logFileLineEdit;
@@ -1780,4 +1785,5 @@
 
   settings.setValue("sslCaCertPath",   _sslCaCertPathLineEdit->text());
+  settings.setValue("sslClientCertPath",   _sslClientCertPathLineEdit->text());
   settings.setValue("sslIgnoreErrors", _sslIgnoreErrorsCheckBox->checkState());
 
@@ -2055,5 +2061,6 @@
   settings.setValue("proxyPort",   _proxyPortLineEdit->text());
   settings.setValue("sslCaCertPath",   _sslCaCertPathLineEdit->text());
-  settings.setValue("sslIgnoreErrors",  _sslIgnoreErrorsCheckBox->checkState());
+  settings.setValue("sslClientCertPath", _sslClientCertPathLineEdit->text());
+  settings.setValue("sslIgnoreErrors", _sslIgnoreErrorsCheckBox->checkState());
 // General
   settings.setValue("logFile",     _logFileLineEdit->text());
Index: trunk/BNC/src/bncwindow.h
===================================================================
--- trunk/BNC/src/bncwindow.h	(revision 9790)
+++ trunk/BNC/src/bncwindow.h	(revision 9795)
@@ -134,4 +134,5 @@
     QLineEdit* _proxyPortLineEdit;
     QLineEdit* _sslCaCertPathLineEdit;
+    QLineEdit* _sslClientCertPathLineEdit;
     QCheckBox* _sslIgnoreErrorsCheckBox;
     QLineEdit* _outFileLineEdit;
Index: trunk/BNC/src/upload/bncuploadcaster.cpp
===================================================================
--- trunk/BNC/src/upload/bncuploadcaster.cpp	(revision 9790)
+++ trunk/BNC/src/upload/bncuploadcaster.cpp	(revision 9795)
@@ -79,4 +79,7 @@
       _secure = true;
       _casterOutPort = 443;
+      // Generate filenames to consider a potential client certificate and private key
+      _crtFileName = settings.value("sslClientCertPath").toString() + _casterOutHost + QString(".%1.crt").arg(_casterOutPort);
+      _keyFileName = settings.value("sslClientCertPath").toString() + _casterOutHost + QString(".%1.key").arg(_casterOutPort);
     }
   }
@@ -215,5 +218,18 @@
     _outSocket->ignoreSslErrors();
   } else {
-    _outSocket->setSslConfiguration(BNC_SSL_CONFIG);
+    bncSslConfig sslConfig = BNC_SSL_CONFIG;
+    QFile clientCrtFile(_crtFileName);
+    QFile privateKeyFile(_keyFileName);
+    if ( clientCrtFile.exists() && privateKeyFile.exists()) {
+      // set local certificate
+      clientCrtFile.open(QIODevice::ReadOnly);
+      QSslCertificate clientCrt(&clientCrtFile);
+      sslConfig.setLocalCertificate(clientCrt);
+      // set private key if available
+      privateKeyFile.open(QIODevice::ReadOnly);
+      QSslKey privateKey(&privateKeyFile, QSsl::Rsa);
+      sslConfig.setPrivateKey(privateKey);
+    }
+    _outSocket->setSslConfiguration(sslConfig);
     connect(_outSocket, SIGNAL(sslErrors(QList<QSslError>)), this, SLOT(slotSslErrors(QList<QSslError>)));
   }
Index: trunk/BNC/src/upload/bncuploadcaster.h
===================================================================
--- trunk/BNC/src/upload/bncuploadcaster.h	(revision 9790)
+++ trunk/BNC/src/upload/bncuploadcaster.h	(revision 9795)
@@ -8,4 +8,5 @@
 #include <QThread>
 #include <QSslError>
+#include <QSslKey>
 #include <iostream>
 
@@ -50,4 +51,6 @@
   QString     _proxyOutHost;
   int         _proxyOutPort;
+  QString     _crtFileName;
+  QString     _keyFileName;
   QString     _userName;
   QString     _password;
