summaryrefslogtreecommitdiffstats
path: root/src/network/ssl/qsslsocket_openssl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/network/ssl/qsslsocket_openssl.cpp')
-rw-r--r--src/network/ssl/qsslsocket_openssl.cpp193
1 files changed, 103 insertions, 90 deletions
diff --git a/src/network/ssl/qsslsocket_openssl.cpp b/src/network/ssl/qsslsocket_openssl.cpp
index 94b1568..5033393 100644
--- a/src/network/ssl/qsslsocket_openssl.cpp
+++ b/src/network/ssl/qsslsocket_openssl.cpp
@@ -71,6 +71,9 @@ QT_BEGIN_NAMESPACE
PtrCertFindCertificateInStore QSslSocketPrivate::ptrCertFindCertificateInStore = 0;
PtrCertCloseStore QSslSocketPrivate::ptrCertCloseStore = 0;
#elif defined(Q_OS_SYMBIAN)
+#include <e32base.h>
+#include <e32std.h>
+#include <e32debug.h>
#include <QtCore/private/qcore_symbian_p.h>
#endif
@@ -570,120 +573,138 @@ void QSslSocketPrivate::resetDefaultCiphers()
#if defined(Q_OS_SYMBIAN)
-QCertificateRetriever::QCertificateRetriever(QCertificateConsumer* parent)
- : CActive(EPriorityStandard)
- , certStore(0)
- , certFilter(0)
- , consumer(parent)
- , currentCertificateIndex(0)
- , certDescriptor(0, 0)
+CSymbianCertificateRetriever::CSymbianCertificateRetriever() : CActive(CActive::EPriorityStandard),
+ iSequenceError(KErrNone)
{
- CActiveScheduler::Add(this);
- QT_TRAP_THROWING(certStore = CUnifiedCertStore::NewL(qt_s60GetRFs(), EFalse));
- QT_TRAP_THROWING(certFilter = CCertAttributeFilter::NewL());
- certFilter->SetFormat(EX509Certificate);
}
-QCertificateRetriever::~QCertificateRetriever()
+CSymbianCertificateRetriever::~CSymbianCertificateRetriever()
{
- delete certFilter;
- delete certStore;
- Cancel();
+ iThread.Close();
}
-void QCertificateRetriever::fetch()
+CSymbianCertificateRetriever* CSymbianCertificateRetriever::NewL()
{
- certStore->Initialize(iStatus);
- state = Initializing;
- SetActive();
+ CSymbianCertificateRetriever* self = new (ELeave) CSymbianCertificateRetriever();
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ CleanupStack::Pop();
+ return self;
}
-void QCertificateRetriever::list()
+int CSymbianCertificateRetriever::GetCertificates(QList<QByteArray> &certificates)
{
- certStore->List(certs, *certFilter, iStatus);
- state = Listing;
- SetActive();
+ iCertificates = &certificates;
+
+ TRequestStatus status;
+ iThread.Logon(status);
+ iThread.Resume();
+ User::WaitForRequest(status);
+ if (iThread.ExitType() == EExitKill)
+ return KErrDied;
+ else
+ return status.Int(); // Logon() completes with the thread's exit value
}
-void QCertificateRetriever::retrieveNextCertificate()
+void CSymbianCertificateRetriever::doThreadEntryL()
{
- CCTCertInfo* cert = certs[currentCertificateIndex];
- currentCertificate.resize(cert->Size());
- certDescriptor.Set((TUint8*)currentCertificate.data(), 0, currentCertificate.size());
- certStore->Retrieve(*cert, certDescriptor, iStatus);
- state = RetrievingCertificates;
+ CActiveScheduler* activeScheduler = new (ELeave) CActiveScheduler;
+ CleanupStack::PushL(activeScheduler);
+ CActiveScheduler::Install(activeScheduler);
+
+ CActiveScheduler::Add(this);
+
+ // These aren't deleted in the destructor so leaving the to CS is ok
+ iCertStore = CUnifiedCertStore::NewLC(qt_s60GetRFs(), EFalse);
+ iCertFilter = CCertAttributeFilter::NewLC();
+
+ // Kick off the sequence by initializing the cert store
+ iState = Initializing;
+ iCertStore->Initialize(iStatus);
SetActive();
-}
-void QCertificateRetriever::RunL()
-{
- QT_TRYCATCH_LEAVING(run());
+ CActiveScheduler::Start();
+
+ // Sequence complete, clean up
+
+ // These MUST be cleaned up before the installed CActiveScheduler is destroyed and can't be left to the
+ // destructor of CSymbianCertificateRetriever. Otherwise the destructor of CActiveScheduler will get
+ // stuck.
+ iCertInfos.Close();
+ CleanupStack::PopAndDestroy(3); // activeScheduler, iCertStore, iCertFilter
}
-void QCertificateRetriever::run()
+
+TInt CSymbianCertificateRetriever::ThreadEntryPoint(TAny* aParams)
{
- switch (state) {
- case Initializing:
- list();
- break;
- case Listing:
- currentCertificateIndex = 0;
- retrieveNextCertificate();
- break;
- case RetrievingCertificates:
- consumer->addEncodedCertificate(currentCertificate);
- currentCertificate = QByteArray();
+ CTrapCleanup* cleanupStack = CTrapCleanup::New();
- currentCertificateIndex++;
+ CSymbianCertificateRetriever* self = (CSymbianCertificateRetriever*) aParams;
+ TRAPD(err, self->doThreadEntryL());
+ delete cleanupStack;
- if (currentCertificateIndex < certs.Count())
- retrieveNextCertificate();
- else
- consumer->finish();
- break;
- }
+ // doThreadEntryL() can leave only before the retrieval sequence is started
+ if (err)
+ return err;
+ else
+ return self->iSequenceError; // return any error that occured during the retrieval
}
-void QCertificateRetriever::DoCancel()
+void CSymbianCertificateRetriever::ConstructL()
{
- switch (state) {
- case Initializing:
- certStore->CancelInitialize();
- break;
- case Listing:
- certStore->CancelList();
- break;
- case RetrievingCertificates:
- certStore->CancelRetrieve();
- break;
- }
+ User::LeaveIfError(iThread.Create(_L("CertWorkerThread"),
+ CSymbianCertificateRetriever::ThreadEntryPoint, 16384, NULL, this));
}
-QCertificateConsumer::QCertificateConsumer(QObject* parent)
- : QObject(parent)
- , retriever(0)
+void CSymbianCertificateRetriever::DoCancel()
{
+ // We never cancel the sequence
}
-QCertificateConsumer::~QCertificateConsumer()
+TInt CSymbianCertificateRetriever::RunError(TInt aError)
{
- delete retriever;
+ // If something goes wrong in the sequence, abort the sequence
+ iSequenceError = aError; // this gets reported to the client in the TRequestStatus
+ CActiveScheduler::Stop();
+ return KErrNone;
}
-void QCertificateConsumer::finish()
+void CSymbianCertificateRetriever::GetCertificateL()
{
- delete retriever;
- retriever = 0;
- emit finished();
+ CCTCertInfo* certInfo = iCertInfos[iCurrentCertIndex];
+ iCertificateData.resize(certInfo->Size());
+ TPtr8 des((TUint8*)iCertificateData.data(), 0, iCertificateData.size());
+ iCertStore->Retrieve(*certInfo, des, iStatus);
+ iState = RetrievingCertificates;
+ SetActive();
}
-void QCertificateConsumer::start()
+void CSymbianCertificateRetriever::RunL()
{
- retriever = new QCertificateRetriever(this);
- Q_CHECK_PTR(retriever);
- retriever->fetch();
-}
+ switch (iState) {
+ case Initializing:
+ iState = Listing;
+ iCertStore->List(iCertInfos, *iCertFilter, iStatus);
+ SetActive();
+ break;
+ case Listing:
+ iCurrentCertIndex = 0;
+ GetCertificateL();
+ break;
+
+ case RetrievingCertificates:
+ iCertificates->append(iCertificateData);
+ iCertificateData = QByteArray();
+ iCurrentCertIndex++;
+ if (iCurrentCertIndex < iCertInfos.Count())
+ GetCertificateL();
+ else
+ // Stop the scheduler to return to the thread entry function
+ CActiveScheduler::Stop();
+ break;
+ }
+}
#endif // defined(Q_OS_SYMBIAN)
QList<QSslCertificate> QSslSocketPrivate::systemCaCertificates()
@@ -760,23 +781,15 @@ QList<QSslCertificate> QSslSocketPrivate::systemCaCertificates()
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;
+ QList<QByteArray> certs;
+ QScopedPointer<CSymbianCertificateRetriever> retriever(CSymbianCertificateRetriever::NewL());
- 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()) {
+ retriever->GetCertificates(certs);
+ foreach (const QByteArray &encodedCert, certs) {
QSslCertificate cert(encodedCert, QSsl::Der);
if (!cert.isNull())
systemCerts.append(cert);
}
-
- delete consumer;
- delete certThread;
#endif
return systemCerts;