summaryrefslogtreecommitdiffstats
path: root/src/network
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@nokia.com>2010-07-06 11:33:47 (GMT)
committerSimon Hausmann <simon.hausmann@nokia.com>2010-07-06 11:33:47 (GMT)
commit4a1d231cd5e0b756a919642b9faf35146a190b95 (patch)
tree087f3188835d782345ca84a45e75459e19f8328f /src/network
parent78f48dc47dd7ea52f2ad979a7fd5289da9f22e66 (diff)
downloadQt-4a1d231cd5e0b756a919642b9faf35146a190b95.zip
Qt-4a1d231cd5e0b756a919642b9faf35146a190b95.tar.gz
Qt-4a1d231cd5e0b756a919642b9faf35146a190b95.tar.bz2
Support QSslSocket::systemCaCertificates() on Symbian
Implemented access to the unified certificate store on Symbian with Shane and Peter's help. Task-number: QTBUG-11399 Reviewed-by: Shane Kearns <shane.kearns@accenture.com> Reviewed-by: Peter Hartmann <peter.hartmann@nokia.com>
Diffstat (limited to 'src/network')
-rw-r--r--src/network/network.pro2
-rw-r--r--src/network/ssl/qsslsocket_openssl.cpp134
-rw-r--r--src/network/ssl/qsslsocket_openssl_p.h64
3 files changed, 199 insertions, 1 deletions
diff --git a/src/network/network.pro b/src/network/network.pro
index 8582d8a..7ed7d3a 100644
--- a/src/network/network.pro
+++ b/src/network/network.pro
@@ -27,5 +27,5 @@ QMAKE_LIBS += $$QMAKE_LIBS_NETWORK
symbian {
TARGET.UID3=0x2001B2DE
- LIBS += -lesock -linsock
+ LIBS += -lesock -linsock -lcertstore -lefsrv -lctframework
}
diff --git a/src/network/ssl/qsslsocket_openssl.cpp b/src/network/ssl/qsslsocket_openssl.cpp
index cad8ca7..d7088ee 100644
--- a/src/network/ssl/qsslsocket_openssl.cpp
+++ b/src/network/ssl/qsslsocket_openssl.cpp
@@ -68,6 +68,8 @@
PtrCertOpenSystemStoreW QSslSocketPrivate::ptrCertOpenSystemStoreW = 0;
PtrCertFindCertificateInStore QSslSocketPrivate::ptrCertFindCertificateInStore = 0;
PtrCertCloseStore QSslSocketPrivate::ptrCertCloseStore = 0;
+#elif defined(Q_OS_SYMBIAN)
+#include <QtCore/private/qcore_symbian_p.h>
#endif
QT_BEGIN_NAMESPACE
@@ -565,6 +567,119 @@ void QSslSocketPrivate::resetDefaultCiphers()
setDefaultCiphers(ciphers);
}
+#if defined(Q_OS_SYMBIAN)
+
+QCertificateRetriever::QCertificateRetriever(QCertificateConsumer* parent)
+ : CActive(EPriorityStandard)
+ , certStore(0)
+ , certFilter(0)
+ , consumer(parent)
+ , currentCertificateIndex(0)
+ , certDescriptor(0, 0)
+{
+ CActiveScheduler::Add(this);
+ QT_TRAP_THROWING(certStore = CUnifiedCertStore::NewL(qt_s60GetRFs(), EFalse));
+ QT_TRAP_THROWING(certFilter = CCertAttributeFilter::NewL());
+ certFilter->SetFormat(EX509Certificate);
+}
+
+QCertificateRetriever::~QCertificateRetriever()
+{
+ delete certFilter;
+ delete certStore;
+ Cancel();
+}
+
+void QCertificateRetriever::fetch()
+{
+ certStore->Initialize(iStatus);
+ state = Initializing;
+ SetActive();
+}
+
+void QCertificateRetriever::list()
+{
+ certStore->List(certs, *certFilter, iStatus);
+ state = Listing;
+ SetActive();
+}
+
+void QCertificateRetriever::retrieveNextCertificate()
+{
+ CCTCertInfo* cert = certs[currentCertificateIndex];
+ currentCertificate.resize(cert->Size());
+ certDescriptor.Set((TUint8*)currentCertificate.data(), 0, currentCertificate.size());
+ certStore->Retrieve(*cert, certDescriptor, iStatus);
+ state = RetrievingCertificates;
+ SetActive();
+}
+
+void QCertificateRetriever::RunL()
+{
+ switch (state) {
+ case Initializing:
+ list();
+ break;
+ case Listing:
+ currentCertificateIndex = 0;
+ retrieveNextCertificate();
+ break;
+ case RetrievingCertificates:
+ consumer->addEncodedCertificate(currentCertificate);
+ currentCertificate = QByteArray();
+
+ currentCertificateIndex++;
+
+ if (currentCertificateIndex < certs.Count())
+ retrieveNextCertificate();
+ else
+ consumer->finish();
+ break;
+ }
+}
+
+void QCertificateRetriever::DoCancel()
+{
+ switch (state) {
+ case Initializing:
+ certStore->CancelInitialize();
+ break;
+ case Listing:
+ certStore->CancelList();
+ break;
+ case RetrievingCertificates:
+ certStore->CancelRetrieve();
+ break;
+ }
+}
+
+QCertificateConsumer::QCertificateConsumer(QObject* parent)
+ : QObject(parent)
+ , retriever(0)
+{
+}
+
+QCertificateConsumer::~QCertificateConsumer()
+{
+ delete retriever;
+}
+
+void QCertificateConsumer::finish()
+{
+ delete retriever;
+ retriever = 0;
+ emit finished();
+}
+
+void QCertificateConsumer::start()
+{
+ retriever = new QCertificateRetriever(this);
+ Q_CHECK_PTR(retriever);
+ retriever->fetch();
+}
+
+#endif // defined(Q_OS_SYMBIAN)
+
QList<QSslCertificate> QSslSocketPrivate::systemCaCertificates()
{
ensureInitialized();
@@ -638,7 +753,26 @@ QList<QSslCertificate> QSslSocketPrivate::systemCaCertificates()
systemCerts.append(QSslCertificate::fromPath(QLatin1String("/usr/lib/ssl/certs/*.pem"), QSsl::Pem, QRegExp::Wildcard)); // Gentoo, Mandrake
systemCerts.append(QSslCertificate::fromPath(QLatin1String("/usr/share/ssl/*.pem"), QSsl::Pem, QRegExp::Wildcard)); // Centos, Redhat, SuSE
systemCerts.append(QSslCertificate::fromPath(QLatin1String("/usr/local/ssl/*.pem"), QSsl::Pem, QRegExp::Wildcard)); // Normal OpenSSL Tarball
+#elif defined(Q_OS_SYMBIAN)
+ QThread* certThread = new QThread;
+
+ QCertificateConsumer *consumer = new QCertificateConsumer();
+ consumer->moveToThread(certThread);
+ QObject::connect(certThread, SIGNAL(started()), consumer, SLOT(start()));
+ QObject::connect(consumer, SIGNAL(finished()), certThread, SLOT(quit()), Qt::DirectConnection);
+
+ certThread->start();
+ certThread->wait();
+ foreach (const QByteArray &encodedCert, consumer->encodedCertificates()) {
+ QSslCertificate cert(encodedCert, QSsl::Der);
+ if (!cert.isNull())
+ systemCerts.append(cert);
+ }
+
+ delete consumer;
+ delete certThread;
#endif
+
return systemCerts;
}
diff --git a/src/network/ssl/qsslsocket_openssl_p.h b/src/network/ssl/qsslsocket_openssl_p.h
index 3c08757..e41320d 100644
--- a/src/network/ssl/qsslsocket_openssl_p.h
+++ b/src/network/ssl/qsslsocket_openssl_p.h
@@ -118,6 +118,70 @@ public:
static QList<QSslCertificate> STACKOFX509_to_QSslCertificates(STACK_OF(X509) *x509);
};
+#if defined(Q_OS_SYMBIAN)
+#include <unifiedcertstore.h> // link against certstore.lib
+#include <ccertattributefilter.h> // link against ctframework.lib
+
+class QCertificateRetriever;
+
+class QCertificateConsumer : public QObject
+{
+ Q_OBJECT
+public:
+ QCertificateConsumer(QObject* parent = 0);
+ ~QCertificateConsumer();
+
+ void finish();
+
+ void addEncodedCertificate(const QByteArray& certificate)
+ { certificates.append(certificate); }
+ QList<QByteArray> encodedCertificates() const { return certificates; }
+
+public slots:
+ void start();
+
+signals:
+ void finished();
+
+private:
+ QList<QByteArray> certificates;
+ QCertificateRetriever *retriever;
+};
+
+
+class QCertificateRetriever : public CActive
+{
+public:
+ QCertificateRetriever(QCertificateConsumer* consumer);
+ ~QCertificateRetriever();
+
+ void fetch();
+
+private:
+ virtual void RunL();
+ virtual void DoCancel();
+
+ void list();
+ void retrieveNextCertificate();
+
+ enum {
+ Initializing,
+ Listing,
+ RetrievingCertificates
+ } state;
+
+ CUnifiedCertStore* certStore;
+ RMPointerArray<CCTCertInfo> certs;
+ CCertAttributeFilter* certFilter;
+ QCertificateConsumer* consumer;
+ int currentCertificateIndex;
+ QByteArray currentCertificate;
+ TPtr8 certDescriptor;
+};
+
+#endif
+
+
QT_END_NAMESPACE
#endif