mirror of
https://github.com/QuasarApp/qca.git
synced 2025-04-28 12:34:31 +00:00
support for tracking written TLS bytes
svn path=/trunk/kdesupport/qca/; revision=257147
This commit is contained in:
parent
eaa4a1973c
commit
231ec39c5b
1
TODO
1
TODO
@ -1,5 +1,6 @@
|
||||
* plugins: thread safety ?
|
||||
* make qca into a real installable library
|
||||
* tls: support shutting down the session
|
||||
|
||||
* dsa
|
||||
* diffie-hellman
|
||||
|
@ -40,7 +40,7 @@ public:
|
||||
connect(sasl, SIGNAL(needParams(bool, bool, bool, bool)), SLOT(sasl_needParams(bool, bool, bool, bool)));
|
||||
connect(sasl, SIGNAL(authenticated()), SLOT(sasl_authenticated()));
|
||||
connect(sasl, SIGNAL(readyRead()), SLOT(sasl_readyRead()));
|
||||
connect(sasl, SIGNAL(readyReadOutgoing()), SLOT(sasl_readyReadOutgoing()));
|
||||
connect(sasl, SIGNAL(readyReadOutgoing(int)), SLOT(sasl_readyReadOutgoing(int)));
|
||||
connect(sasl, SIGNAL(error(int)), SLOT(sasl_error(int)));
|
||||
}
|
||||
|
||||
@ -172,7 +172,7 @@ private slots:
|
||||
processInbuf();
|
||||
}
|
||||
|
||||
void sasl_readyReadOutgoing()
|
||||
void sasl_readyReadOutgoing(int)
|
||||
{
|
||||
QByteArray a = sasl->readOutgoing();
|
||||
sock->writeBlock(a.data(), a.size());
|
||||
@ -341,7 +341,7 @@ public:
|
||||
connect(sasl, SIGNAL(nextStep(const QByteArray &)), SLOT(sasl_nextStep(const QByteArray &)));
|
||||
connect(sasl, SIGNAL(authenticated()), SLOT(sasl_authenticated()));
|
||||
connect(sasl, SIGNAL(readyRead()), SLOT(sasl_readyRead()));
|
||||
connect(sasl, SIGNAL(readyReadOutgoing()), SLOT(sasl_readyReadOutgoing()));
|
||||
connect(sasl, SIGNAL(readyReadOutgoing(int)), SLOT(sasl_readyReadOutgoing(int)));
|
||||
connect(sasl, SIGNAL(error(int)), SLOT(sasl_error(int)));
|
||||
|
||||
sock->setSocket(s);
|
||||
@ -446,7 +446,7 @@ private slots:
|
||||
processInbuf();
|
||||
}
|
||||
|
||||
void sasl_readyReadOutgoing()
|
||||
void sasl_readyReadOutgoing(int)
|
||||
{
|
||||
QByteArray a = sasl->readOutgoing();
|
||||
toWrite = a.size();
|
||||
|
@ -60,7 +60,7 @@ public:
|
||||
ssl = new QCA::TLS;
|
||||
connect(ssl, SIGNAL(handshaken()), SLOT(ssl_handshaken()));
|
||||
connect(ssl, SIGNAL(readyRead()), SLOT(ssl_readyRead()));
|
||||
connect(ssl, SIGNAL(readyReadOutgoing()), SLOT(ssl_readyReadOutgoing()));
|
||||
connect(ssl, SIGNAL(readyReadOutgoing(int)), SLOT(ssl_readyReadOutgoing(int)));
|
||||
connect(ssl, SIGNAL(error(int)), SLOT(ssl_error(int)));
|
||||
|
||||
cert.fromPEM(pemdata_cert);
|
||||
@ -163,7 +163,7 @@ private slots:
|
||||
ssl->write(b);
|
||||
}
|
||||
|
||||
void ssl_readyReadOutgoing()
|
||||
void ssl_readyReadOutgoing(int)
|
||||
{
|
||||
QByteArray a = ssl->readOutgoing();
|
||||
|
||||
|
@ -130,7 +130,7 @@ public:
|
||||
ssl = new QCA::TLS;
|
||||
connect(ssl, SIGNAL(handshaken()), SLOT(ssl_handshaken()));
|
||||
connect(ssl, SIGNAL(readyRead()), SLOT(ssl_readyRead()));
|
||||
connect(ssl, SIGNAL(readyReadOutgoing()), SLOT(ssl_readyReadOutgoing()));
|
||||
connect(ssl, SIGNAL(readyReadOutgoing(int)), SLOT(ssl_readyReadOutgoing(int)));
|
||||
connect(ssl, SIGNAL(error(int)), SLOT(ssl_error(int)));
|
||||
|
||||
rootCerts.setAutoDelete(true);
|
||||
@ -222,7 +222,7 @@ private slots:
|
||||
printf("%s", cs.data());
|
||||
}
|
||||
|
||||
void ssl_readyReadOutgoing()
|
||||
void ssl_readyReadOutgoing(int)
|
||||
{
|
||||
QByteArray a = ssl->readOutgoing();
|
||||
sock->writeBlock(a.data(), a.size());
|
||||
|
@ -964,6 +964,7 @@ public:
|
||||
BIO *rbio, *wbio;
|
||||
CertContext cc;
|
||||
int vr;
|
||||
bool v_eof;
|
||||
|
||||
TLSContext()
|
||||
{
|
||||
@ -1009,6 +1010,12 @@ public:
|
||||
mode = Idle;
|
||||
cc.reset();
|
||||
vr = QCA::TLS::Unknown;
|
||||
v_eof = false;
|
||||
}
|
||||
|
||||
bool eof() const
|
||||
{
|
||||
return v_eof;
|
||||
}
|
||||
|
||||
bool startClient(const QPtrList<QCA_CertContext> &store, const QCA_CertContext &cert, const QCA_RSAKeyContext &key)
|
||||
@ -1154,20 +1161,49 @@ public:
|
||||
vr = code;
|
||||
}
|
||||
|
||||
bool encode(const QByteArray &plain, QByteArray *to_net)
|
||||
bool encode(const QByteArray &plain, QByteArray *to_net, int *enc)
|
||||
{
|
||||
if(mode != Active)
|
||||
return false;
|
||||
appendArray(&sendQueue, plain);
|
||||
|
||||
int encoded = 0;
|
||||
if(sendQueue.size() > 0) {
|
||||
int ret = SSL_write(ssl, sendQueue.data(), sendQueue.size());
|
||||
|
||||
enum { Good, Continue, Done, Error };
|
||||
int m;
|
||||
if(ret <= 0) {
|
||||
int x = SSL_get_error(ssl, ret);
|
||||
if(x == SSL_ERROR_WANT_READ || x == SSL_ERROR_WANT_WRITE)
|
||||
m = Continue;
|
||||
else if(x == SSL_ERROR_ZERO_RETURN)
|
||||
m = Done;
|
||||
else
|
||||
m = Error;
|
||||
}
|
||||
else {
|
||||
m = Good;
|
||||
encoded = ret;
|
||||
int newsize = sendQueue.size() - encoded;
|
||||
char *r = sendQueue.data();
|
||||
memmove(r, r + encoded, newsize);
|
||||
sendQueue.resize(newsize);
|
||||
}
|
||||
|
||||
if(m == Done) {
|
||||
sendQueue.resize(0);
|
||||
if(ret <= 0)
|
||||
v_eof = true;
|
||||
return false;
|
||||
}
|
||||
if(m == Error) {
|
||||
sendQueue.resize(0);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
*to_net = readOutgoing();
|
||||
*enc = encoded;
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1186,6 +1222,10 @@ public:
|
||||
int x = SSL_get_error(ssl, ret);
|
||||
if(x == SSL_ERROR_WANT_READ || x == SSL_ERROR_WANT_WRITE)
|
||||
break;
|
||||
else if(x == SSL_ERROR_ZERO_RETURN) {
|
||||
v_eof = true;
|
||||
return false;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
@ -1202,6 +1242,24 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
QByteArray unprocessed()
|
||||
{
|
||||
QByteArray a;
|
||||
int size = BIO_pending(rbio);
|
||||
if(size <= 0)
|
||||
return a;
|
||||
a.resize(size);
|
||||
|
||||
int r = BIO_read(rbio, a.data(), size);
|
||||
if(r <= 0) {
|
||||
a.resize(0);
|
||||
return a;
|
||||
}
|
||||
if(r != size)
|
||||
a.resize(r);
|
||||
return a;
|
||||
}
|
||||
|
||||
QByteArray readOutgoing()
|
||||
{
|
||||
QByteArray a;
|
||||
|
45
src/qca.cpp
45
src/qca.cpp
@ -865,6 +865,9 @@ public:
|
||||
to_net.resize(0);
|
||||
host = "";
|
||||
hostMismatch = false;
|
||||
cert = Cert();
|
||||
bytesEncoded = 0;
|
||||
tryMore = false;
|
||||
}
|
||||
|
||||
void appendArray(QByteArray *a, const QByteArray &b)
|
||||
@ -877,6 +880,8 @@ public:
|
||||
Cert cert;
|
||||
QCA_TLSContext *c;
|
||||
QByteArray in, out, to_net, from_net;
|
||||
int bytesEncoded;
|
||||
bool tryMore;
|
||||
bool handshaken;
|
||||
QString host;
|
||||
bool hostMismatch;
|
||||
@ -912,6 +917,11 @@ void TLS::setCertificateStore(const QPtrList<Cert> &store)
|
||||
d->store.append(cert->d->c);
|
||||
}
|
||||
|
||||
void TLS::reset()
|
||||
{
|
||||
d->reset();
|
||||
}
|
||||
|
||||
bool TLS::startClient(const QString &host)
|
||||
{
|
||||
d->reset();
|
||||
@ -933,6 +943,11 @@ bool TLS::startServer()
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TLS::isHandshaken() const
|
||||
{
|
||||
return d->handshaken;
|
||||
}
|
||||
|
||||
void TLS::write(const QByteArray &a)
|
||||
{
|
||||
d->appendArray(&d->out, a);
|
||||
@ -981,6 +996,7 @@ void TLS::update()
|
||||
int r = d->c->handshake(d->from_net, &a);
|
||||
d->from_net.resize(0);
|
||||
if(r == QCA_TLSContext::Error) {
|
||||
reset();
|
||||
error(ErrHandshake);
|
||||
return;
|
||||
}
|
||||
@ -1001,21 +1017,37 @@ void TLS::update()
|
||||
}
|
||||
|
||||
if(d->handshaken) {
|
||||
if(!d->out.isEmpty()) {
|
||||
if(!d->out.isEmpty() || d->tryMore) {
|
||||
d->tryMore = false;
|
||||
QByteArray a;
|
||||
bool ok = d->c->encode(d->out, &a);
|
||||
int enc;
|
||||
bool more = false;
|
||||
bool ok = d->c->encode(d->out, &a, &enc);
|
||||
bool eof = d->c->eof();
|
||||
if(ok && enc < (int)d->out.size())
|
||||
more = true;
|
||||
d->out.resize(0);
|
||||
if(eof)
|
||||
return;
|
||||
if(!ok) {
|
||||
reset();
|
||||
error(ErrCrypt);
|
||||
return;
|
||||
}
|
||||
d->bytesEncoded += enc;
|
||||
if(more)
|
||||
d->tryMore = true;
|
||||
d->appendArray(&d->to_net, a);
|
||||
}
|
||||
if(!d->from_net.isEmpty() || force_read) {
|
||||
QByteArray a, b;
|
||||
bool ok = d->c->decode(d->from_net, &a, &b);
|
||||
bool eof = d->c->eof();
|
||||
d->from_net.resize(0);
|
||||
if(eof)
|
||||
return;
|
||||
if(!ok) {
|
||||
reset();
|
||||
error(ErrCrypt);
|
||||
return;
|
||||
}
|
||||
@ -1027,8 +1059,11 @@ void TLS::update()
|
||||
readyRead();
|
||||
}
|
||||
|
||||
if(!d->to_net.isEmpty())
|
||||
readyReadOutgoing();
|
||||
if(!d->to_net.isEmpty()) {
|
||||
int bytes = d->bytesEncoded;
|
||||
d->bytesEncoded = 0;
|
||||
readyReadOutgoing(bytes);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1387,7 +1422,7 @@ void SASL::write(const QByteArray &a)
|
||||
int oldsize = d->outbuf.size();
|
||||
d->outbuf.resize(oldsize + b.size());
|
||||
memcpy(d->outbuf.data() + oldsize, b.data(), b.size());
|
||||
readyReadOutgoing();
|
||||
readyReadOutgoing(a.size());
|
||||
}
|
||||
|
||||
QByteArray SASL::read()
|
||||
|
@ -314,8 +314,10 @@ namespace QCA
|
||||
void setCertificate(const Cert &cert, const RSAKey &key);
|
||||
void setCertificateStore(const QPtrList<Cert> &store); // note: store must persist
|
||||
|
||||
void reset();
|
||||
bool startClient(const QString &host="");
|
||||
bool startServer();
|
||||
bool isHandshaken() const;
|
||||
|
||||
// plain (application side)
|
||||
void write(const QByteArray &a);
|
||||
@ -332,7 +334,7 @@ namespace QCA
|
||||
signals:
|
||||
void handshaken();
|
||||
void readyRead();
|
||||
void readyReadOutgoing();
|
||||
void readyReadOutgoing(int plainBytes);
|
||||
void error(int);
|
||||
|
||||
private slots:
|
||||
@ -404,7 +406,7 @@ namespace QCA
|
||||
|
||||
// for security layer
|
||||
void readyRead();
|
||||
void readyReadOutgoing();
|
||||
void readyReadOutgoing(int plainBytes);
|
||||
|
||||
// error
|
||||
void error(int);
|
||||
|
@ -134,8 +134,9 @@ public:
|
||||
virtual bool startServer(const QPtrList<QCA_CertContext> &store, const QCA_CertContext &cert, const QCA_RSAKeyContext &key)=0;
|
||||
|
||||
virtual int handshake(const QByteArray &in, QByteArray *out)=0;
|
||||
virtual bool encode(const QByteArray &plain, QByteArray *to_net)=0;
|
||||
virtual bool encode(const QByteArray &plain, QByteArray *to_net, int *encoded)=0;
|
||||
virtual bool decode(const QByteArray &from_net, QByteArray *plain, QByteArray *to_net)=0;
|
||||
virtual bool eof() const=0;
|
||||
|
||||
virtual QCA_CertContext *peerCertificate() const=0;
|
||||
virtual int validityResult() const=0;
|
||||
|
Loading…
x
Reference in New Issue
Block a user