147
154
//----------------------------------------------------------------------------
149
156
//----------------------------------------------------------------------------
153
ResetSessionAndData = 1,
157
157
class TLS::Private : public QObject
185
CheckPeerCertificate,
186
CertificateRequested,
192
Action(int _type) : type(_type)
201
// signal connected flags
202
bool connect_hostNameReceived;
203
bool connect_certificateRequested;
204
bool connect_peerCertificateAvailable;
205
bool connect_handshaken;
207
// persistent settings (survives ResetSessionAndData)
166
208
CertificateChain localCert;
167
209
PrivateKey localKey;
168
210
CertificateCollection trusted;
169
211
bool con_ssfMode;
170
212
int con_minSSF, con_maxSSF;
171
213
QStringList con_cipherSuites;
172
216
QList<CertificateInfoOrdered> issuerList;
173
217
TLSSession session;
224
TLSContext::SessionInfo sessionInfo;
225
QTimer actionTrigger;
227
QList<Action> actionQueue;
230
bool emitted_hostNameReceived;
231
bool emitted_certificateRequested;
232
bool emitted_peerCertificateAvailable;
234
// data (survives ResetSession)
178
235
CertificateChain peerCert;
179
236
Validity peerValidity;
181
237
bool hostMismatch;
182
TLSContext::SessionInfo sessionInfo;
184
241
QByteArray in, out;
185
242
QByteArray to_net, from_net;
243
QByteArray unprocessed;
187
246
LayerTracker layer;
189
249
QList<QByteArray> packet_in, packet_out;
190
250
QList<QByteArray> packet_to_net, packet_from_net;
251
int packet_out_pending; // packet count
191
252
QList<int> packet_to_net_encoded;
193
bool connect_hostNameReceived, connect_certificateRequested, connect_handshaken;
195
enum { OpStart, OpUpdate };
199
bool handshaken, closing;
204
Private(TLS *_q, TLS::Mode _mode) : QObject(_q), q(_q), mode(_mode)
254
Private(TLS *_q, TLS::Mode _mode) : QObject(_q), q(_q), mode(_mode), actionTrigger(this)
206
256
// c is 0 during initial reset, so we don't redundantly reset it
208
258
connect_hostNameReceived = false;
209
259
connect_certificateRequested = false;
260
connect_peerCertificateAvailable = false;
210
261
connect_handshaken = false;
264
connect(&actionTrigger, SIGNAL(timeout()), SLOT(doNextAction()));
265
actionTrigger.setSingleShot(true);
215
269
c = static_cast<TLSContext *>(q->context());
301
370
c->setMTU(packet_mtu);
372
QCA_logTextMessage(QString("tls[%1]: c->start()").arg(q->objectName()), Logger::Information);
309
if(!handshaken || closing)
379
QCA_logTextMessage(QString("tls[%1]: close").arg(q->objectName()), Logger::Information);
381
if(state != Connected)
316
388
void continueAfterStep()
318
//printf("continuing\n");
390
QCA_logTextMessage(QString("tls[%1]: continueAfterStep").arg(q->objectName()), Logger::Information);
399
void processNextAction()
401
if(actionQueue.isEmpty())
405
QCA_logTextMessage(QString("tls[%1]: need_update").arg(q->objectName()), Logger::Information);
411
Action a = actionQueue.takeFirst();
413
// set up for the next one, if necessary
414
if(!actionQueue.isEmpty() || need_update)
416
if(!actionTrigger.isActive())
417
actionTrigger.start();
420
if(a.type == Action::ReadyRead)
424
else if(a.type == Action::ReadyReadOutgoing)
426
emit q->readyReadOutgoing();
428
else if(a.type == Action::Handshaken)
432
// write any app data waiting during handshake
436
if(!actionTrigger.isActive())
437
actionTrigger.start();
440
QCA_logTextMessage(QString("tls[%1]: handshaken").arg(q->objectName()), Logger::Information);
442
if(connect_handshaken)
445
emit q->handshaken();
448
else if(a.type == Action::Close)
450
unprocessed = c->unprocessed();
454
else if(a.type == Action::CheckPeerCertificate)
456
peerCert = c->peerCertificateChain();
457
if(!peerCert.isEmpty())
459
peerValidity = c->peerCertificateValidity();
460
if(peerValidity == ValidityGood && !host.isEmpty() && !peerCert.primary().matchesHostName(host))
464
if(connect_peerCertificateAvailable)
467
emitted_peerCertificateAvailable = true;
468
emit q->peerCertificateAvailable();
471
else if(a.type == Action::CertificateRequested)
473
issuerList = c->issuerList();
474
if(connect_certificateRequested)
477
emitted_certificateRequested = true;
478
emit q->certificateRequested();
481
else if(a.type == Action::HostNameReceived)
483
if(connect_hostNameReceived)
486
emitted_hostNameReceived = true;
487
emit q->hostNameReceived();
326
//printf("update attempt\n");
494
QCA_logTextMessage(QString("tls[%1]: update").arg(q->objectName()), Logger::Information);
498
QCA_logTextMessage(QString("tls[%1]: ignoring update while blocked").arg(q->objectName()), Logger::Information);
502
if(!actionQueue.isEmpty())
504
QCA_logTextMessage(QString("tls[%1]: ignoring update while processing actions").arg(q->objectName()), Logger::Information);
330
509
// only allow one operation at a time
512
QCA_logTextMessage(QString("tls[%1]: ignoring update while operation active").arg(q->objectName()), Logger::Information);
334
//printf("update\n");
518
QByteArray arg_from_net, arg_from_app;
520
if(state == Handshaking)
338
// FIXME: optimize this somehow. we need to force
339
// the update after start() succeeds, but not in any
340
// other case afaict.
522
// during handshake, only send from_net (no app data)
342
524
if(mode == TLS::Stream)
344
// during handshake, only send from_net (no app data)
345
//if(!from_net.isEmpty())
348
c->update(from_net, QByteArray());
526
arg_from_net = from_net;
354
531
// note: there may not be a packet
355
QByteArray pkt = packet_from_net.takeFirst();
358
c->update(pkt, QByteArray());
532
if(!packet_from_net.isEmpty())
533
arg_from_net = packet_from_net.takeFirst();
363
538
if(mode == TLS::Stream)
365
// FIXME: we should be able to send both at once,
366
// but if we do this then qca-ossl gives us
367
// broken security layer. probably a bug in
370
// otherwise, send both from_net and out
371
/*if(!from_net.isEmpty() || !out.isEmpty())
374
pending_write += out.size();
375
c->update(from_net, out);
380
540
if(!from_net.isEmpty())
383
c->update(from_net, QByteArray());
542
arg_from_net = from_net;
384
543
from_net.clear();
386
else //if(!out.isEmpty())
389
pending_write += out.size();
390
c->update(QByteArray(), out);
548
out_pending += out.size();
397
QByteArray pkta = packet_from_net.takeFirst();
398
QByteArray pktb = packet_out.takeFirst();
400
packet_to_net_encoded += pktb.size();
401
c->update(pkta, pktb);
555
if(!packet_from_net.isEmpty())
556
arg_from_net = packet_from_net.takeFirst();
558
if(!packet_out.isEmpty())
560
arg_from_app = packet_out.takeFirst();
561
++packet_out_pending;
407
void tls_resultsReady()
409
QPointer<QObject> self = this;
413
//printf("results ready: %d\n", last_op);
415
if(last_op == OpStart)
417
bool ok = c->result() == TLSContext::Success;
566
if(arg_from_net.isEmpty() && arg_from_app.isEmpty() && !maybe_input)
568
QCA_logTextMessage(QString("tls[%1]: ignoring update: no output and no expected input").arg(q->objectName()), Logger::Information);
575
QCA_logTextMessage(QString("tls[%1]: c->update").arg(q->objectName()), Logger::Information);
577
c->update(arg_from_net, arg_from_app);
580
void start_finished()
582
bool ok = c->result() == TLSContext::Success;
586
errorCode = TLS::ErrorInit;
593
// immediately update so we can get the first packet to send
598
void update_finished()
600
TLSContext::Result r = c->result();
601
if(r == TLSContext::Error)
603
if(state == Handshaking || state == Closing)
420
605
reset(ResetSession);
421
errorCode = TLS::ErrorInit;
422
QMetaObject::invokeMethod(q, "error", Qt::QueuedConnection);
431
TLSContext::Result r = c->result();
432
QByteArray a = c->to_net();
436
if(r == TLSContext::Error)
439
errorCode = ErrorHandshake;
440
QMetaObject::invokeMethod(q, "error", Qt::QueuedConnection);
445
if(mode == TLS::Stream)
452
QMetaObject::invokeMethod(q, "readyReadOutgoing", Qt::QueuedConnection);
453
//emit q->readyReadOutgoing();
458
if(r == TLSContext::Success)
460
from_net = c->unprocessed();
462
QMetaObject::invokeMethod(q, "closed", Qt::QueuedConnection);
472
if(r == TLSContext::Error)
475
errorCode = TLS::ErrorHandshake;
476
QMetaObject::invokeMethod(q, "error", Qt::QueuedConnection);
481
if(mode == TLS::Stream)
488
QMetaObject::invokeMethod(q, "readyReadOutgoing", Qt::QueuedConnection);
489
//emit q->readyReadOutgoing();
494
if(r == TLSContext::Success)
496
peerCert = c->peerCertificateChain();
497
if(!peerCert.isEmpty())
499
peerValidity = c->peerCertificateValidity();
500
if(peerValidity == ValidityGood && !host.isEmpty() && !peerCert.primary().matchesHostName(host))
504
sessionInfo = c->sessionInfo();
507
TLSSessionContext *sc = static_cast<TLSSessionContext*>(sessionInfo.id->clone());
512
if(connect_handshaken)
515
emit q->handshaken();
524
bool clientHello = c->clientHelloReceived();
527
host = c->hostName();
530
if(connect_hostNameReceived)
533
emit q->hostNameReceived();
543
bool serverHello = c->serverHelloReceived();
546
if(c->certificateRequested())
548
issuerList = c->issuerList();
549
if(connect_certificateRequested)
552
emit q->certificateRequested();
565
bool ok = (r == TLSContext::Success);
606
errorCode = ErrorHandshake;
568
610
reset(ResetSession);
569
611
errorCode = ErrorCrypt;
570
QMetaObject::invokeMethod(q, "error", Qt::QueuedConnection);
575
QByteArray b = c->to_app();
576
//printf("to_app: %d (%s)\n", b.size(), b.data());
618
QByteArray c_to_net = c->to_net();
619
if(!c_to_net.isEmpty())
621
QCA_logTextMessage(QString("tls[%1]: to_net %2").arg(q->objectName(), QString::number(c_to_net.size())), Logger::Information);
626
if(mode == TLS::Stream)
629
packet_to_net += c_to_net;
631
if(!c_to_net.isEmpty())
632
actionQueue += Action(Action::ReadyReadOutgoing);
634
if(r == TLSContext::Success)
635
actionQueue += Action(Action::Close);
640
else if(state == Handshaking)
642
if(mode == TLS::Stream)
645
packet_to_net += c_to_net;
647
if(!c_to_net.isEmpty())
648
actionQueue += Action(Action::ReadyReadOutgoing);
650
bool clientHello = false;
651
bool serverHello = false;
653
clientHello = c->clientHelloReceived();
655
serverHello = c->serverHelloReceived();
657
// client specifies a host?
658
if(!emitted_hostNameReceived && clientHello)
660
host = c->hostName();
662
actionQueue += Action(Action::HostNameReceived);
665
// successful handshake or server hello means there might be a peer cert
666
if(!emitted_peerCertificateAvailable && (r == TLSContext::Success || (!server && serverHello)))
667
actionQueue += Action(Action::CheckPeerCertificate);
669
// server requests a cert from us?
670
if(!emitted_certificateRequested && (serverHello && c->certificateRequested()))
671
actionQueue += Action(Action::CertificateRequested);
673
if(r == TLSContext::Success)
675
sessionInfo = c->sessionInfo();
678
TLSSessionContext *sc = static_cast<TLSSessionContext*>(sessionInfo.id->clone());
682
actionQueue += Action(Action::Handshaken);
690
QByteArray c_to_app = c->to_app();
691
if(!c_to_app.isEmpty())
693
QCA_logTextMessage(QString("tls[%1]: to_app %2").arg(q->objectName(), QString::number(c_to_app.size())), Logger::Information);
577
696
bool eof = c->eof();
578
int enc = c->encoded();
698
if(!c_to_net.isEmpty())
701
bool io_pending = false;
581
702
if(mode == TLS::Stream)
583
pending_write -= enc;
584
if(pending_write > 0)
704
if(!c_to_net.isEmpty())
589
if(!a.isEmpty() && enc > 0)
718
if(!c_to_net.isEmpty())
719
--packet_out_pending;
721
if(packet_out_pending > 0)
591
enc = packet_to_net_encoded.takeFirst();
592
if(!packet_to_net_encoded.isEmpty())
596
// datagram mode might have more pending out
597
727
if(!packet_out.isEmpty())
604
731
if(mode == TLS::Stream)
735
to_net_encoded += enc;
618
QMetaObject::invokeMethod(q, "readyReadOutgoing", Qt::QueuedConnection);
619
//emit q->readyReadOutgoing();
626
QMetaObject::invokeMethod(q, "readyRead", Qt::QueuedConnection);
627
//emit q->readyRead();
739
packet_to_net += c_to_net;
740
packet_in += c_to_app;
743
if(!c_to_net.isEmpty())
744
actionQueue += Action(Action::ReadyReadOutgoing);
746
if(!c_to_app.isEmpty())
747
actionQueue += Action(Action::ReadyRead);
755
if(eof || io_pending)
757
QCA_logTextMessage(QString("tls[%1]: eof || io_pending").arg(q->objectName()), Logger::Information);
767
void tls_resultsReady()
769
QCA_logTextMessage(QString("tls[%1]: c->resultsReady()").arg(q->objectName()), Logger::Information);
776
if(last_op == OpStart)
782
void tls_dtlsTimeout()
784
QCA_logTextMessage(QString("tls[%1]: c->dtlsTimeout()").arg(q->objectName()), Logger::Information);
641
796
TLS::TLS(QObject *parent, const QString &provider)