2004-11-05 08:54:01 +00:00
|
|
|
/*
|
2005-01-01 02:44:28 +00:00
|
|
|
* Copyright (C) 2003-2005 Justin Karneges <justin@affinix.com>
|
|
|
|
* Copyright (C) 2004,2005 Brad Hards <bradh@frogmouth.net>
|
2004-11-05 08:54:01 +00:00
|
|
|
*
|
|
|
|
* This library is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
|
|
* License as published by the Free Software Foundation; either
|
|
|
|
* version 2.1 of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This library is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
* Lesser General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
|
|
* License along with this library; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
2005-01-01 02:44:28 +00:00
|
|
|
#include "qca_securelayer.h"
|
2004-11-05 08:54:01 +00:00
|
|
|
|
2005-02-27 01:12:26 +00:00
|
|
|
#include <QtCore>
|
2004-11-05 08:54:01 +00:00
|
|
|
#include "qcaprovider.h"
|
|
|
|
|
|
|
|
namespace QCA {
|
|
|
|
|
2005-04-24 19:09:06 +00:00
|
|
|
Provider::Context *getContext(const QString &type, const QString &provider);
|
|
|
|
|
2004-11-05 08:54:01 +00:00
|
|
|
//----------------------------------------------------------------------------
|
|
|
|
// SecureLayer
|
|
|
|
//----------------------------------------------------------------------------
|
2005-02-27 01:12:26 +00:00
|
|
|
SecureLayer::SecureLayer(QObject *parent)
|
|
|
|
:QObject(parent)
|
2004-11-05 08:54:01 +00:00
|
|
|
{
|
2004-11-17 00:28:34 +00:00
|
|
|
}
|
|
|
|
|
2005-07-28 12:17:09 +00:00
|
|
|
bool SecureLayer::isClosable() const
|
2004-11-17 00:28:34 +00:00
|
|
|
{
|
2005-07-28 12:17:09 +00:00
|
|
|
return false;
|
2004-11-05 08:54:01 +00:00
|
|
|
}
|
|
|
|
|
2005-07-28 12:17:09 +00:00
|
|
|
void SecureLayer::close()
|
2004-11-05 08:54:01 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2005-07-28 12:17:09 +00:00
|
|
|
QByteArray SecureLayer::readUnprocessed()
|
2004-11-05 08:54:01 +00:00
|
|
|
{
|
2005-07-28 12:17:09 +00:00
|
|
|
return QByteArray();
|
2004-11-05 08:54:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------------
|
|
|
|
// TLS
|
|
|
|
//----------------------------------------------------------------------------
|
2005-04-24 19:09:06 +00:00
|
|
|
enum ResetMode
|
|
|
|
{
|
|
|
|
ResetSession = 0,
|
|
|
|
ResetSessionAndData = 1,
|
|
|
|
ResetAll = 2
|
|
|
|
};
|
|
|
|
|
2005-07-28 12:17:09 +00:00
|
|
|
class TLS::Private : public QObject
|
2004-11-05 08:54:01 +00:00
|
|
|
{
|
2005-07-28 12:17:09 +00:00
|
|
|
Q_OBJECT
|
2004-11-05 08:54:01 +00:00
|
|
|
public:
|
2005-04-24 19:09:06 +00:00
|
|
|
TLS *q;
|
|
|
|
TLSContext *c;
|
|
|
|
|
|
|
|
CertificateChain localCert;
|
|
|
|
PrivateKey localKey;
|
|
|
|
CertificateCollection trusted;
|
|
|
|
bool con_ssfMode;
|
|
|
|
int con_minSSF, con_maxSSF;
|
|
|
|
QStringList con_cipherSuites;
|
|
|
|
bool tryCompress;
|
|
|
|
|
|
|
|
QString host;
|
|
|
|
CertificateChain peerCert;
|
|
|
|
Validity peerValidity;
|
|
|
|
bool hostMismatch;
|
|
|
|
TLSContext::SessionInfo sessionInfo;
|
|
|
|
|
2005-06-24 23:41:25 +00:00
|
|
|
QByteArray in, out;
|
2005-04-24 19:09:06 +00:00
|
|
|
QByteArray to_net, from_net;
|
|
|
|
|
2005-07-28 12:17:09 +00:00
|
|
|
enum { OpStart, OpHandshake, OpShutdown, OpEncode, OpDecode };
|
|
|
|
int last_op;
|
|
|
|
|
2005-04-24 19:09:06 +00:00
|
|
|
bool handshaken, closing, closed, error;
|
|
|
|
bool tryMore;
|
|
|
|
int bytesEncoded;
|
|
|
|
Error errorCode;
|
|
|
|
|
2005-07-28 12:17:09 +00:00
|
|
|
Private(TLS *_q) : QObject(_q), q(_q)
|
2004-11-05 08:54:01 +00:00
|
|
|
{
|
2005-04-24 19:09:06 +00:00
|
|
|
c = 0;
|
|
|
|
|
|
|
|
reset(ResetAll);
|
2004-11-05 08:54:01 +00:00
|
|
|
}
|
|
|
|
|
2005-07-28 12:17:09 +00:00
|
|
|
void reset(ResetMode mode)
|
2004-11-05 08:54:01 +00:00
|
|
|
{
|
2005-04-24 19:09:06 +00:00
|
|
|
if(c)
|
|
|
|
c->reset();
|
|
|
|
|
|
|
|
host = QString();
|
|
|
|
out.clear();
|
2004-11-05 08:54:01 +00:00
|
|
|
handshaken = false;
|
|
|
|
closing = false;
|
2005-04-24 19:09:06 +00:00
|
|
|
closed = false;
|
|
|
|
error = false;
|
2004-11-05 08:54:01 +00:00
|
|
|
tryMore = false;
|
2005-04-24 19:09:06 +00:00
|
|
|
bytesEncoded = 0;
|
|
|
|
|
|
|
|
if(mode >= ResetSessionAndData)
|
|
|
|
{
|
|
|
|
peerCert = CertificateChain();
|
2005-05-10 04:10:23 +00:00
|
|
|
peerValidity = ErrorValidityUnknown;
|
|
|
|
hostMismatch = false;
|
2005-04-24 19:09:06 +00:00
|
|
|
in.clear();
|
|
|
|
to_net.clear();
|
|
|
|
from_net.clear();
|
|
|
|
}
|
|
|
|
|
|
|
|
if(mode >= ResetAll)
|
|
|
|
{
|
|
|
|
localCert = CertificateChain();
|
|
|
|
localKey = PrivateKey();
|
|
|
|
trusted = CertificateCollection();
|
|
|
|
con_ssfMode = true;
|
|
|
|
con_minSSF = 128;
|
|
|
|
con_maxSSF = -1;
|
|
|
|
con_cipherSuites = QStringList();
|
|
|
|
tryCompress = false;
|
|
|
|
}
|
2004-11-05 08:54:01 +00:00
|
|
|
}
|
|
|
|
|
2005-04-24 19:09:06 +00:00
|
|
|
bool start(bool serverMode)
|
2004-11-05 08:54:01 +00:00
|
|
|
{
|
2005-04-24 19:09:06 +00:00
|
|
|
if(con_ssfMode)
|
|
|
|
c->setConstraints(con_minSSF, con_maxSSF);
|
|
|
|
else
|
|
|
|
c->setConstraints(con_cipherSuites);
|
|
|
|
|
|
|
|
c->setup(trusted, localCert, localKey, tryCompress);
|
|
|
|
|
|
|
|
bool ok;
|
|
|
|
if(serverMode)
|
2005-07-28 12:17:09 +00:00
|
|
|
c->startServer();
|
2005-04-24 19:09:06 +00:00
|
|
|
else
|
2005-07-28 12:17:09 +00:00
|
|
|
c->startClient();
|
|
|
|
last_op = OpStart;
|
|
|
|
c->waitForResultsReady(-1);
|
|
|
|
ok = c->success();
|
2005-04-24 19:09:06 +00:00
|
|
|
if(!ok)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
update();
|
|
|
|
return true;
|
2004-11-05 08:54:01 +00:00
|
|
|
}
|
|
|
|
|
2005-04-24 19:09:06 +00:00
|
|
|
void close()
|
|
|
|
{
|
|
|
|
if(!handshaken || closing)
|
|
|
|
return;
|
|
|
|
|
|
|
|
closing = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void update()
|
|
|
|
{
|
|
|
|
bool wasHandshaken = handshaken;
|
2005-07-28 12:17:09 +00:00
|
|
|
//q->layerUpdateBegin();
|
|
|
|
int _read = q->bytesAvailable();
|
|
|
|
int _readout = q->bytesOutgoingAvailable();
|
|
|
|
bool _closed = closed;
|
|
|
|
bool _error = error;
|
2005-04-24 19:09:06 +00:00
|
|
|
|
|
|
|
if(closing)
|
|
|
|
updateClosing();
|
|
|
|
else
|
|
|
|
updateMain();
|
|
|
|
|
|
|
|
if(!wasHandshaken && handshaken)
|
2005-07-28 12:17:09 +00:00
|
|
|
QMetaObject::invokeMethod(q, "handshaken", Qt::QueuedConnection);
|
|
|
|
|
|
|
|
if(q->bytesAvailable() > _read)
|
|
|
|
{
|
|
|
|
emit q->readyRead();
|
|
|
|
//QMetaObject::invokeMethod(q, "readyRead", Qt::QueuedConnection);
|
|
|
|
}
|
|
|
|
if(q->bytesOutgoingAvailable() > _readout)
|
|
|
|
QMetaObject::invokeMethod(q, "readyReadOutgoing", Qt::QueuedConnection);
|
|
|
|
if(!_closed && closed)
|
|
|
|
QMetaObject::invokeMethod(q, "closed", Qt::QueuedConnection);
|
|
|
|
if(!_error && error)
|
|
|
|
QMetaObject::invokeMethod(q, "error", Qt::QueuedConnection);
|
|
|
|
//q->layerUpdateEnd();
|
2005-04-24 19:09:06 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void updateClosing()
|
|
|
|
{
|
|
|
|
QByteArray a;
|
2005-07-28 12:17:09 +00:00
|
|
|
TLSContext::Result r;
|
|
|
|
c->shutdown(from_net);
|
|
|
|
last_op = OpShutdown;
|
|
|
|
c->waitForResultsReady(-1);
|
|
|
|
a = c->to_net();
|
|
|
|
r = c->handshakeResult();
|
2005-04-24 19:09:06 +00:00
|
|
|
from_net.clear();
|
|
|
|
|
|
|
|
if(r == TLSContext::Error)
|
|
|
|
{
|
2005-07-28 12:17:09 +00:00
|
|
|
reset(ResetSession);
|
2005-04-24 19:09:06 +00:00
|
|
|
error = true;
|
|
|
|
errorCode = ErrorHandshake;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
to_net.append(a);
|
|
|
|
|
|
|
|
if(r == TLSContext::Success)
|
|
|
|
{
|
|
|
|
from_net = c->unprocessed();
|
2005-07-28 12:17:09 +00:00
|
|
|
reset(ResetSession);
|
2005-04-24 19:09:06 +00:00
|
|
|
closed = true;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
2004-11-05 08:54:01 +00:00
|
|
|
|
2005-04-24 19:09:06 +00:00
|
|
|
void updateMain()
|
|
|
|
{
|
|
|
|
bool force_read = false;
|
|
|
|
|
|
|
|
if(!handshaken)
|
|
|
|
{
|
|
|
|
QByteArray a;
|
2005-07-28 12:17:09 +00:00
|
|
|
TLSContext::Result r;
|
|
|
|
c->handshake(from_net);
|
|
|
|
last_op = OpHandshake;
|
|
|
|
c->waitForResultsReady(-1);
|
|
|
|
a = c->to_net();
|
|
|
|
r = c->handshakeResult();
|
2005-04-24 19:09:06 +00:00
|
|
|
from_net.clear();
|
|
|
|
|
|
|
|
if(r == TLSContext::Error)
|
|
|
|
{
|
2005-07-28 12:17:09 +00:00
|
|
|
reset(ResetSession);
|
2005-04-24 19:09:06 +00:00
|
|
|
error = true;
|
|
|
|
errorCode = ErrorHandshake;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
to_net.append(a);
|
|
|
|
|
|
|
|
if(r == TLSContext::Success)
|
|
|
|
{
|
|
|
|
peerCert = c->peerCertificateChain();
|
|
|
|
if(!peerCert.isEmpty())
|
|
|
|
{
|
|
|
|
peerValidity = c->peerCertificateValidity();
|
|
|
|
if(peerValidity == ValidityGood && !host.isEmpty() && !peerCert.primary().matchesHostname(host))
|
|
|
|
hostMismatch = true;
|
|
|
|
}
|
2005-05-06 07:12:35 +00:00
|
|
|
sessionInfo = c->sessionInfo();
|
2005-04-24 19:09:06 +00:00
|
|
|
handshaken = true;
|
|
|
|
force_read = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if(handshaken)
|
|
|
|
{
|
|
|
|
bool eof = false;
|
|
|
|
|
|
|
|
if(!out.isEmpty() || tryMore)
|
|
|
|
{
|
|
|
|
tryMore = false;
|
|
|
|
QByteArray a;
|
|
|
|
int enc;
|
|
|
|
bool more = false;
|
2005-07-28 12:17:09 +00:00
|
|
|
c->encode(out);
|
|
|
|
c->waitForResultsReady(-1);
|
|
|
|
bool ok = c->success();
|
|
|
|
a = c->to_net();
|
|
|
|
enc = c->encoded();
|
2005-04-24 19:09:06 +00:00
|
|
|
eof = c->eof();
|
|
|
|
if(ok && enc < out.size())
|
|
|
|
more = true;
|
|
|
|
out.clear();
|
|
|
|
if(!eof)
|
|
|
|
{
|
|
|
|
if(!ok)
|
|
|
|
{
|
2005-07-28 12:17:09 +00:00
|
|
|
reset(ResetSession);
|
2005-04-24 19:09:06 +00:00
|
|
|
error = true;
|
|
|
|
errorCode = ErrorCrypt;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
bytesEncoded += enc;
|
|
|
|
if(more)
|
|
|
|
tryMore = true;
|
|
|
|
to_net.append(a);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if(!from_net.isEmpty() || force_read)
|
|
|
|
{
|
2005-06-24 23:41:25 +00:00
|
|
|
QByteArray a;
|
2005-04-24 19:09:06 +00:00
|
|
|
QByteArray b;
|
2005-07-28 12:17:09 +00:00
|
|
|
c->decode(from_net);
|
|
|
|
c->waitForResultsReady(-1);
|
|
|
|
bool ok = c->success();
|
|
|
|
a = c->plain();
|
|
|
|
b = c->to_net();
|
2005-04-24 19:09:06 +00:00
|
|
|
eof = c->eof();
|
|
|
|
from_net.clear();
|
|
|
|
if(!ok)
|
|
|
|
{
|
2005-07-28 12:17:09 +00:00
|
|
|
reset(ResetSession);
|
2005-04-24 19:09:06 +00:00
|
|
|
error = true;
|
|
|
|
errorCode = ErrorCrypt;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
in.append(a);
|
|
|
|
to_net.append(b);
|
|
|
|
}
|
|
|
|
|
|
|
|
if(eof)
|
|
|
|
{
|
|
|
|
close();
|
|
|
|
updateClosing();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2005-07-28 12:17:09 +00:00
|
|
|
|
|
|
|
private slots:
|
|
|
|
void tls_resultsReady()
|
|
|
|
{
|
|
|
|
//printf("results ready\n");
|
|
|
|
}
|
2004-11-05 08:54:01 +00:00
|
|
|
};
|
|
|
|
|
2005-02-27 01:12:26 +00:00
|
|
|
TLS::TLS(QObject *parent, const QString &provider)
|
|
|
|
:SecureLayer(parent), Algorithm("tls", provider)
|
2004-11-05 08:54:01 +00:00
|
|
|
{
|
2005-04-24 19:09:06 +00:00
|
|
|
d = new Private(this);
|
|
|
|
d->c = static_cast<TLSContext *>(context());
|
2005-07-28 12:17:09 +00:00
|
|
|
d->c->setParent(d);
|
|
|
|
connect(d->c, SIGNAL(resultsReady()), d, SLOT(tls_resultsReady()));
|
2004-11-05 08:54:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
TLS::~TLS()
|
|
|
|
{
|
2005-07-28 12:17:09 +00:00
|
|
|
d->c->setParent(0);
|
2004-11-05 08:54:01 +00:00
|
|
|
delete d;
|
|
|
|
}
|
|
|
|
|
2005-02-24 10:07:14 +00:00
|
|
|
void TLS::reset()
|
|
|
|
{
|
2005-04-24 19:09:06 +00:00
|
|
|
d->reset(ResetAll);
|
2005-02-24 10:07:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
QStringList TLS::supportedCipherSuites(const QString &provider)
|
|
|
|
{
|
2005-04-24 19:09:06 +00:00
|
|
|
QStringList list;
|
|
|
|
const TLSContext *c = static_cast<const TLSContext *>(getContext("tls", provider));
|
|
|
|
if(!c)
|
|
|
|
return list;
|
|
|
|
list = c->supportedCipherSuites();
|
|
|
|
delete c;
|
|
|
|
return list;
|
2005-02-24 10:07:14 +00:00
|
|
|
}
|
|
|
|
|
2005-01-14 06:36:12 +00:00
|
|
|
void TLS::setCertificate(const CertificateChain &cert, const PrivateKey &key)
|
2004-11-05 08:54:01 +00:00
|
|
|
{
|
2005-04-24 19:09:06 +00:00
|
|
|
d->localCert = cert;
|
|
|
|
d->localKey = key;
|
2004-11-05 08:54:01 +00:00
|
|
|
}
|
|
|
|
|
2005-03-28 07:11:58 +00:00
|
|
|
void TLS::setTrustedCertificates(const CertificateCollection &trusted)
|
2004-11-05 08:54:01 +00:00
|
|
|
{
|
2005-04-24 19:09:06 +00:00
|
|
|
d->trusted = trusted;
|
2004-11-05 08:54:01 +00:00
|
|
|
}
|
|
|
|
|
2004-11-17 00:28:34 +00:00
|
|
|
void TLS::setConstraints(SecurityLevel s)
|
|
|
|
{
|
2005-04-24 19:09:06 +00:00
|
|
|
int min;
|
|
|
|
switch(s)
|
|
|
|
{
|
|
|
|
case SL_None:
|
|
|
|
min = 0;
|
|
|
|
break;
|
|
|
|
case SL_Integrity:
|
|
|
|
min = 1;
|
|
|
|
break;
|
|
|
|
case SL_Export:
|
|
|
|
min = 40;
|
|
|
|
break;
|
|
|
|
case SL_Baseline:
|
|
|
|
min = 128;
|
|
|
|
break;
|
|
|
|
case SL_High:
|
|
|
|
min = 129;
|
|
|
|
break;
|
|
|
|
case SL_Highest:
|
2005-07-06 21:33:27 +00:00
|
|
|
min = qMax(129, d->c->maxSSF());
|
2005-04-24 19:09:06 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
d->con_ssfMode = true;
|
|
|
|
d->con_minSSF = min;
|
|
|
|
d->con_maxSSF = -1;
|
2004-11-17 00:28:34 +00:00
|
|
|
}
|
|
|
|
|
2005-04-24 19:09:06 +00:00
|
|
|
void TLS::setConstraints(int minSSF, int maxSSF)
|
2004-11-17 00:28:34 +00:00
|
|
|
{
|
2005-04-24 19:09:06 +00:00
|
|
|
d->con_ssfMode = true;
|
|
|
|
d->con_minSSF = minSSF;
|
|
|
|
d->con_maxSSF = maxSSF;
|
2004-11-17 00:28:34 +00:00
|
|
|
}
|
|
|
|
|
2005-02-24 10:07:14 +00:00
|
|
|
void TLS::setConstraints(const QStringList &cipherSuiteList)
|
|
|
|
{
|
2005-04-24 19:09:06 +00:00
|
|
|
d->con_ssfMode = false;
|
|
|
|
d->con_cipherSuites = cipherSuiteList;
|
2005-02-24 10:07:14 +00:00
|
|
|
}
|
|
|
|
|
2005-01-27 16:42:44 +00:00
|
|
|
bool TLS::canCompress(const QString &provider)
|
|
|
|
{
|
2005-04-24 19:09:06 +00:00
|
|
|
bool ok = false;
|
|
|
|
const TLSContext *c = static_cast<const TLSContext *>(getContext("tls", provider));
|
|
|
|
if(!c)
|
|
|
|
return ok;
|
|
|
|
ok = c->canCompress();
|
|
|
|
delete c;
|
|
|
|
return ok;
|
2005-01-27 16:42:44 +00:00
|
|
|
}
|
|
|
|
|
2004-11-17 00:28:34 +00:00
|
|
|
void TLS::setCompressionEnabled(bool b)
|
|
|
|
{
|
2005-04-24 19:09:06 +00:00
|
|
|
d->tryCompress = b;
|
2004-11-17 00:28:34 +00:00
|
|
|
}
|
|
|
|
|
2005-07-28 12:17:09 +00:00
|
|
|
void TLS::startClient(const QString &host)
|
2004-11-05 08:54:01 +00:00
|
|
|
{
|
2005-04-24 19:09:06 +00:00
|
|
|
d->reset(ResetSessionAndData);
|
2004-11-05 08:54:01 +00:00
|
|
|
d->host = host;
|
2005-07-28 12:17:09 +00:00
|
|
|
//layerUpdateBegin();
|
|
|
|
if(!d->start(false))
|
|
|
|
{
|
|
|
|
d->reset(ResetSession);
|
|
|
|
d->error = true;
|
|
|
|
d->errorCode = ErrorInit;
|
|
|
|
QMetaObject::invokeMethod(this, "error", Qt::QueuedConnection);
|
|
|
|
}
|
|
|
|
//layerUpdateEnd();
|
2004-11-05 08:54:01 +00:00
|
|
|
}
|
|
|
|
|
2005-07-28 12:17:09 +00:00
|
|
|
void TLS::startServer()
|
2004-11-05 08:54:01 +00:00
|
|
|
{
|
2005-04-24 19:09:06 +00:00
|
|
|
d->reset(ResetSessionAndData);
|
2005-07-28 12:17:09 +00:00
|
|
|
//layerUpdateBegin();
|
|
|
|
if(!d->start(true))
|
|
|
|
{
|
|
|
|
d->reset(ResetSession);
|
|
|
|
d->error = true;
|
|
|
|
d->errorCode = ErrorInit;
|
|
|
|
QMetaObject::invokeMethod(this, "error", Qt::QueuedConnection);
|
|
|
|
}
|
|
|
|
//layerUpdateEnd();
|
2004-11-05 08:54:01 +00:00
|
|
|
}
|
|
|
|
|
2005-02-24 10:07:14 +00:00
|
|
|
bool TLS::isHandshaken() const
|
2004-11-05 08:54:01 +00:00
|
|
|
{
|
2005-02-24 10:07:14 +00:00
|
|
|
return d->handshaken;
|
2004-11-05 08:54:01 +00:00
|
|
|
}
|
|
|
|
|
2005-02-25 03:36:58 +00:00
|
|
|
bool TLS::isCompressed() const
|
|
|
|
{
|
2005-04-24 19:09:06 +00:00
|
|
|
return d->sessionInfo.isCompressed;
|
2005-02-25 03:36:58 +00:00
|
|
|
}
|
|
|
|
|
2005-02-24 10:07:14 +00:00
|
|
|
TLS::Version TLS::version() const
|
2004-11-05 08:54:01 +00:00
|
|
|
{
|
2005-04-24 19:09:06 +00:00
|
|
|
return d->sessionInfo.version;
|
2004-11-05 08:54:01 +00:00
|
|
|
}
|
|
|
|
|
2005-02-24 10:07:14 +00:00
|
|
|
QString TLS::cipherSuite() const
|
2004-11-17 00:28:34 +00:00
|
|
|
{
|
2005-04-24 19:09:06 +00:00
|
|
|
return d->sessionInfo.cipherSuite;
|
2004-11-17 00:28:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
int TLS::cipherBits() const
|
|
|
|
{
|
2005-04-24 19:09:06 +00:00
|
|
|
return d->sessionInfo.cipherBits;
|
2004-11-17 00:28:34 +00:00
|
|
|
}
|
|
|
|
|
2005-02-24 10:07:14 +00:00
|
|
|
int TLS::cipherMaxBits() const
|
|
|
|
{
|
2005-04-24 19:09:06 +00:00
|
|
|
return d->sessionInfo.cipherMaxBits;
|
2005-02-24 10:07:14 +00:00
|
|
|
}
|
|
|
|
|
2004-11-05 08:54:01 +00:00
|
|
|
TLS::Error TLS::errorCode() const
|
|
|
|
{
|
|
|
|
return d->errorCode;
|
|
|
|
}
|
|
|
|
|
2005-02-24 10:07:14 +00:00
|
|
|
TLS::IdentityResult TLS::peerIdentityResult() const
|
|
|
|
{
|
2005-04-24 19:09:06 +00:00
|
|
|
if(d->peerCert.isEmpty())
|
|
|
|
return NoCertificate;
|
2005-02-24 10:07:14 +00:00
|
|
|
|
2005-04-24 19:09:06 +00:00
|
|
|
if(d->peerValidity != ValidityGood)
|
|
|
|
return InvalidCertificate;
|
2005-02-24 10:07:14 +00:00
|
|
|
|
|
|
|
if(d->hostMismatch)
|
|
|
|
return HostMismatch;
|
|
|
|
|
|
|
|
return Valid;
|
|
|
|
}
|
|
|
|
|
2005-02-25 06:51:06 +00:00
|
|
|
Validity TLS::peerCertificateValidity() const
|
2005-02-24 10:07:14 +00:00
|
|
|
{
|
2005-04-24 19:09:06 +00:00
|
|
|
return d->peerValidity;
|
2005-02-24 10:07:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
CertificateChain TLS::localCertificateChain() const
|
|
|
|
{
|
2005-04-24 19:09:06 +00:00
|
|
|
return d->localCert;
|
2005-02-24 10:07:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
CertificateChain TLS::peerCertificateChain() const
|
|
|
|
{
|
2005-04-24 19:09:06 +00:00
|
|
|
return d->peerCert;
|
2005-02-24 10:07:14 +00:00
|
|
|
}
|
|
|
|
|
2004-11-05 08:54:01 +00:00
|
|
|
bool TLS::isClosable() const
|
|
|
|
{
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2004-11-07 11:40:11 +00:00
|
|
|
int TLS::bytesAvailable() const
|
|
|
|
{
|
2005-04-24 19:09:06 +00:00
|
|
|
return d->in.size();
|
2004-11-07 11:40:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
int TLS::bytesOutgoingAvailable() const
|
|
|
|
{
|
2005-04-24 19:09:06 +00:00
|
|
|
return d->to_net.size();
|
2004-11-07 11:40:11 +00:00
|
|
|
}
|
|
|
|
|
2005-02-24 10:07:14 +00:00
|
|
|
void TLS::close()
|
|
|
|
{
|
2005-04-24 19:09:06 +00:00
|
|
|
d->close();
|
|
|
|
d->update();
|
2005-02-24 10:07:14 +00:00
|
|
|
}
|
|
|
|
|
2005-06-24 23:41:25 +00:00
|
|
|
void TLS::write(const QByteArray &a)
|
2004-11-07 11:40:11 +00:00
|
|
|
{
|
2005-04-24 19:09:06 +00:00
|
|
|
d->out.append(a);
|
|
|
|
d->update();
|
2004-11-05 08:54:01 +00:00
|
|
|
}
|
|
|
|
|
2005-06-24 23:41:25 +00:00
|
|
|
QByteArray TLS::read()
|
2004-11-05 08:54:01 +00:00
|
|
|
{
|
2005-06-24 23:41:25 +00:00
|
|
|
QByteArray a = d->in;
|
2005-04-24 19:09:06 +00:00
|
|
|
d->in.clear();
|
2004-11-05 08:54:01 +00:00
|
|
|
return a;
|
|
|
|
}
|
|
|
|
|
|
|
|
void TLS::writeIncoming(const QByteArray &a)
|
|
|
|
{
|
2005-04-24 19:09:06 +00:00
|
|
|
d->from_net.append(a);
|
|
|
|
d->update();
|
2004-11-05 08:54:01 +00:00
|
|
|
}
|
|
|
|
|
2004-11-13 10:13:12 +00:00
|
|
|
QByteArray TLS::readOutgoing(int *plainBytes)
|
2004-11-05 08:54:01 +00:00
|
|
|
{
|
2005-02-27 01:12:26 +00:00
|
|
|
QByteArray a = d->to_net;
|
2005-04-24 19:09:06 +00:00
|
|
|
d->to_net.clear();
|
|
|
|
if(plainBytes)
|
|
|
|
*plainBytes = d->bytesEncoded;
|
|
|
|
d->bytesEncoded = 0;
|
2004-11-05 08:54:01 +00:00
|
|
|
return a;
|
|
|
|
}
|
|
|
|
|
2005-04-24 19:09:06 +00:00
|
|
|
QByteArray TLS::readUnprocessed()
|
2004-11-05 08:54:01 +00:00
|
|
|
{
|
2005-02-27 01:12:26 +00:00
|
|
|
QByteArray a = d->from_net;
|
2005-04-24 19:09:06 +00:00
|
|
|
d->from_net.clear();
|
2004-11-05 08:54:01 +00:00
|
|
|
return a;
|
|
|
|
}
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------------
|
|
|
|
// SASL
|
|
|
|
//----------------------------------------------------------------------------
|
2004-11-13 10:13:12 +00:00
|
|
|
QString *saslappname = 0;
|
2004-11-05 08:54:01 +00:00
|
|
|
class SASL::Private
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
void setSecurityProps()
|
|
|
|
{
|
|
|
|
c->setSecurityProps(noPlain, noActive, noDict, noAnon, reqForward, reqCreds, reqMutual, ssfmin, ssfmax, ext_authid, ext_ssf);
|
|
|
|
}
|
|
|
|
|
|
|
|
// security opts
|
|
|
|
bool noPlain, noActive, noDict, noAnon, reqForward, reqCreds, reqMutual;
|
|
|
|
int ssfmin, ssfmax;
|
|
|
|
QString ext_authid;
|
|
|
|
int ext_ssf;
|
|
|
|
|
|
|
|
bool tried;
|
|
|
|
SASLContext *c;
|
2005-02-27 01:12:26 +00:00
|
|
|
//QHostAddress localAddr, remoteAddr;
|
2004-11-05 08:54:01 +00:00
|
|
|
int localPort, remotePort;
|
|
|
|
QByteArray stepData;
|
|
|
|
bool allowCSF;
|
|
|
|
bool first, server;
|
|
|
|
Error errorCode;
|
|
|
|
|
|
|
|
QByteArray inbuf, outbuf;
|
|
|
|
};
|
|
|
|
|
2005-02-27 01:12:26 +00:00
|
|
|
SASL::SASL(QObject *parent, const QString &provider)
|
|
|
|
:SecureLayer(parent), Algorithm("sasl", provider)
|
2004-11-05 08:54:01 +00:00
|
|
|
{
|
|
|
|
d = new Private;
|
|
|
|
d->c = (SASLContext *)context();
|
|
|
|
reset();
|
|
|
|
}
|
|
|
|
|
|
|
|
SASL::~SASL()
|
|
|
|
{
|
|
|
|
delete d;
|
|
|
|
}
|
|
|
|
|
|
|
|
void SASL::reset()
|
|
|
|
{
|
|
|
|
d->localPort = -1;
|
|
|
|
d->remotePort = -1;
|
|
|
|
|
|
|
|
d->noPlain = false;
|
|
|
|
d->noActive = false;
|
|
|
|
d->noDict = false;
|
|
|
|
d->noAnon = false;
|
|
|
|
d->reqForward = false;
|
|
|
|
d->reqCreds = false;
|
|
|
|
d->reqMutual = false;
|
|
|
|
d->ssfmin = 0;
|
|
|
|
d->ssfmax = 0;
|
2004-12-31 04:21:08 +00:00
|
|
|
d->ext_authid = QString();
|
2004-11-05 08:54:01 +00:00
|
|
|
d->ext_ssf = 0;
|
|
|
|
|
|
|
|
d->inbuf.resize(0);
|
|
|
|
d->outbuf.resize(0);
|
|
|
|
|
|
|
|
d->c->reset();
|
|
|
|
}
|
|
|
|
|
|
|
|
SASL::Error SASL::errorCode() const
|
|
|
|
{
|
|
|
|
return d->errorCode;
|
|
|
|
}
|
|
|
|
|
2004-11-13 10:13:12 +00:00
|
|
|
SASL::AuthCondition SASL::authCondition() const
|
2004-11-05 08:54:01 +00:00
|
|
|
{
|
2004-11-13 10:13:12 +00:00
|
|
|
return (AuthCondition)d->c->authError();
|
2004-11-05 08:54:01 +00:00
|
|
|
}
|
|
|
|
|
2004-11-17 00:28:34 +00:00
|
|
|
void SASL::setConstraints(AuthFlags f, SecurityLevel s)
|
2004-11-05 08:54:01 +00:00
|
|
|
{
|
2004-11-17 00:28:34 +00:00
|
|
|
Q_UNUSED(f);
|
|
|
|
Q_UNUSED(s);
|
|
|
|
|
|
|
|
/*d->noPlain = (f & SAllowPlain) ? false: true;
|
2004-11-05 08:54:01 +00:00
|
|
|
d->noAnon = (f & SAllowAnonymous) ? false: true;
|
2004-11-13 10:13:12 +00:00
|
|
|
//d->noActive = (f & SAllowActiveVulnerable) ? false: true;
|
|
|
|
//d->noDict = (f & SAllowDictVulnerable) ? false: true;
|
2004-11-05 08:54:01 +00:00
|
|
|
d->reqForward = (f & SRequireForwardSecrecy) ? true : false;
|
|
|
|
d->reqCreds = (f & SRequirePassCredentials) ? true : false;
|
2004-11-17 00:28:34 +00:00
|
|
|
d->reqMutual = (f & SRequireMutualAuth) ? true : false;*/
|
|
|
|
|
|
|
|
//d->ssfmin = minSSF;
|
|
|
|
//d->ssfmax = maxSSF;
|
|
|
|
}
|
2004-11-05 08:54:01 +00:00
|
|
|
|
2004-11-17 00:28:34 +00:00
|
|
|
void SASL::setConstraints(AuthFlags, int, int)
|
|
|
|
{
|
2004-11-05 08:54:01 +00:00
|
|
|
}
|
|
|
|
|
2004-12-20 08:08:39 +00:00
|
|
|
void SASL::setExternalAuthId(const QString &authid)
|
2004-11-05 08:54:01 +00:00
|
|
|
{
|
|
|
|
d->ext_authid = authid;
|
|
|
|
}
|
|
|
|
|
|
|
|
void SASL::setExternalSSF(int x)
|
|
|
|
{
|
|
|
|
d->ext_ssf = x;
|
|
|
|
}
|
|
|
|
|
2005-02-28 09:01:59 +00:00
|
|
|
void SASL::setLocalAddr(const QString &addr, quint16 port)
|
2004-11-05 08:54:01 +00:00
|
|
|
{
|
2005-02-28 09:01:59 +00:00
|
|
|
Q_UNUSED(addr);
|
|
|
|
//d->localAddr = addr;
|
2004-11-05 08:54:01 +00:00
|
|
|
d->localPort = port;
|
|
|
|
}
|
|
|
|
|
2005-02-28 09:01:59 +00:00
|
|
|
void SASL::setRemoteAddr(const QString &addr, quint16 port)
|
2004-11-05 08:54:01 +00:00
|
|
|
{
|
2005-02-28 09:01:59 +00:00
|
|
|
Q_UNUSED(addr);
|
|
|
|
//d->remoteAddr = addr;
|
2004-11-05 08:54:01 +00:00
|
|
|
d->remotePort = port;
|
2005-02-28 09:01:59 +00:00
|
|
|
}
|
2004-11-05 08:54:01 +00:00
|
|
|
|
2005-07-28 12:17:09 +00:00
|
|
|
void SASL::startClient(const QString &service, const QString &host, const QStringList &mechlist, ClientSendMode)
|
2004-11-05 08:54:01 +00:00
|
|
|
{
|
2004-11-13 10:13:12 +00:00
|
|
|
SASLContext::HostPort la, ra;
|
2005-02-27 01:12:26 +00:00
|
|
|
/*if(d->localPort != -1) {
|
2004-11-05 08:54:01 +00:00
|
|
|
la.addr = d->localAddr;
|
|
|
|
la.port = d->localPort;
|
|
|
|
}
|
|
|
|
if(d->remotePort != -1) {
|
|
|
|
ra.addr = d->remoteAddr;
|
|
|
|
ra.port = d->remotePort;
|
2005-02-27 01:12:26 +00:00
|
|
|
}*/
|
2004-11-05 08:54:01 +00:00
|
|
|
|
2005-02-28 07:31:19 +00:00
|
|
|
//d->allowCSF = allowClientSendFirst;
|
2004-11-05 08:54:01 +00:00
|
|
|
d->c->setCoreProps(service, host, d->localPort != -1 ? &la : 0, d->remotePort != -1 ? &ra : 0);
|
|
|
|
d->setSecurityProps();
|
|
|
|
|
|
|
|
if(!d->c->clientStart(mechlist))
|
2005-07-28 12:17:09 +00:00
|
|
|
{
|
|
|
|
// TODO: ErrorInit
|
|
|
|
return;
|
|
|
|
}
|
2004-11-05 08:54:01 +00:00
|
|
|
d->first = true;
|
|
|
|
d->server = false;
|
|
|
|
d->tried = false;
|
|
|
|
QTimer::singleShot(0, this, SLOT(tryAgain()));
|
2005-07-28 12:17:09 +00:00
|
|
|
//return true;
|
2004-11-05 08:54:01 +00:00
|
|
|
}
|
|
|
|
|
2005-07-28 12:17:09 +00:00
|
|
|
void SASL::startServer(const QString &service, const QString &host, const QString &realm, QStringList *mechlist, ServerSendMode)
|
2004-11-05 08:54:01 +00:00
|
|
|
{
|
2005-02-28 07:31:19 +00:00
|
|
|
//Q_UNUSED(allowServerSendLast);
|
2004-11-17 00:28:34 +00:00
|
|
|
|
2004-11-13 10:13:12 +00:00
|
|
|
SASLContext::HostPort la, ra;
|
2005-02-27 01:12:26 +00:00
|
|
|
/*if(d->localPort != -1) {
|
2004-11-05 08:54:01 +00:00
|
|
|
la.addr = d->localAddr;
|
|
|
|
la.port = d->localPort;
|
|
|
|
}
|
|
|
|
if(d->remotePort != -1) {
|
|
|
|
ra.addr = d->remoteAddr;
|
|
|
|
ra.port = d->remotePort;
|
2005-02-27 01:12:26 +00:00
|
|
|
}*/
|
2004-11-05 08:54:01 +00:00
|
|
|
|
|
|
|
d->c->setCoreProps(service, host, d->localPort != -1 ? &la : 0, d->remotePort != -1 ? &ra : 0);
|
|
|
|
d->setSecurityProps();
|
|
|
|
|
|
|
|
QString appname;
|
|
|
|
if(saslappname)
|
|
|
|
appname = *saslappname;
|
|
|
|
else
|
|
|
|
appname = "qca";
|
|
|
|
|
|
|
|
if(!d->c->serverStart(realm, mechlist, appname))
|
2005-07-28 12:17:09 +00:00
|
|
|
{
|
|
|
|
// TODO: ErrorInit
|
|
|
|
return;
|
|
|
|
}
|
2004-11-05 08:54:01 +00:00
|
|
|
d->first = true;
|
|
|
|
d->server = true;
|
|
|
|
d->tried = false;
|
2005-07-28 12:17:09 +00:00
|
|
|
//return true;
|
2004-11-05 08:54:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void SASL::putServerFirstStep(const QString &mech)
|
|
|
|
{
|
2004-11-13 10:13:12 +00:00
|
|
|
/*int r =*/ d->c->serverFirstStep(mech, 0);
|
|
|
|
//handleServerFirstStep(r);
|
2004-11-05 08:54:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void SASL::putServerFirstStep(const QString &mech, const QByteArray &clientInit)
|
|
|
|
{
|
2004-11-13 10:13:12 +00:00
|
|
|
/*int r =*/ d->c->serverFirstStep(mech, &clientInit);
|
|
|
|
//handleServerFirstStep(r);
|
2004-11-05 08:54:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void SASL::putStep(const QByteArray &stepData)
|
|
|
|
{
|
2005-02-27 01:12:26 +00:00
|
|
|
d->stepData = stepData;
|
2004-11-13 10:13:12 +00:00
|
|
|
//tryAgain();
|
2004-11-05 08:54:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void SASL::setUsername(const QString &user)
|
|
|
|
{
|
|
|
|
d->c->setClientParams(&user, 0, 0, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
void SASL::setAuthzid(const QString &authzid)
|
|
|
|
{
|
|
|
|
d->c->setClientParams(0, &authzid, 0, 0);
|
|
|
|
}
|
|
|
|
|
2004-11-13 10:13:12 +00:00
|
|
|
void SASL::setPassword(const QSecureArray &pass)
|
2004-11-05 08:54:01 +00:00
|
|
|
{
|
|
|
|
d->c->setClientParams(0, 0, &pass, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
void SASL::setRealm(const QString &realm)
|
|
|
|
{
|
|
|
|
d->c->setClientParams(0, 0, 0, &realm);
|
|
|
|
}
|
|
|
|
|
|
|
|
void SASL::continueAfterParams()
|
|
|
|
{
|
2004-11-13 10:13:12 +00:00
|
|
|
//tryAgain();
|
2004-11-05 08:54:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void SASL::continueAfterAuthCheck()
|
|
|
|
{
|
2004-11-13 10:13:12 +00:00
|
|
|
//tryAgain();
|
2004-11-05 08:54:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
int SASL::ssf() const
|
|
|
|
{
|
|
|
|
return d->c->security();
|
|
|
|
}
|
|
|
|
|
2004-11-13 10:13:12 +00:00
|
|
|
int SASL::bytesAvailable() const
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int SASL::bytesOutgoingAvailable() const
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2005-06-24 23:41:25 +00:00
|
|
|
void SASL::write(const QByteArray &a)
|
2004-11-13 10:13:12 +00:00
|
|
|
{
|
|
|
|
Q_UNUSED(a);
|
|
|
|
}
|
|
|
|
|
2005-06-24 23:41:25 +00:00
|
|
|
QByteArray SASL::read()
|
2004-11-13 10:13:12 +00:00
|
|
|
{
|
2005-06-24 23:41:25 +00:00
|
|
|
return QByteArray();
|
2004-11-13 10:13:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void SASL::writeIncoming(const QByteArray &a)
|
|
|
|
{
|
|
|
|
Q_UNUSED(a);
|
|
|
|
}
|
|
|
|
|
|
|
|
QByteArray SASL::readOutgoing(int *plainBytes)
|
|
|
|
{
|
|
|
|
Q_UNUSED(plainBytes);
|
|
|
|
return QByteArray();
|
|
|
|
}
|
|
|
|
|
2004-11-05 08:54:01 +00:00
|
|
|
}
|
2005-07-28 12:17:09 +00:00
|
|
|
|
|
|
|
#include "qca_securelayer.moc"
|