1
/****************************************************************************
2
** sslfilter.h - simple OpenSSL encryption I/O
3
** Copyright (C) 2001, 2002 Justin Karneges
5
** This program is free software; you can redistribute it and/or
6
** modify it under the terms of the GNU General Public License
7
** as published by the Free Software Foundation; either version 2
8
** of the License, or (at your option) any later version.
10
** This program is distributed in the hope that it will be useful,
11
** but WITHOUT ANY WARRANTY; without even the implied warranty of
12
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
** GNU General Public License for more details.
15
** You should have received a copy of the GNU General Public License
16
** along with this program; if not, write to the Free Software
17
** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,USA.
19
****************************************************************************/
29
/****************************************************************************
32
This class handles an OpenSSL session. It works independent of fds and
33
sockets. Pass incoming socket data to it via putIncomingSSLData(). When
34
OpenSSL wants to send data out the channel, outgoingSSLDataReady() will
35
be emitted and you can get the data to be sent with getOutgoingSSLData().
37
Once you have these hooks set up, the rest is easy. Use send() to encrypt
38
data and use recv() to retrieve unencrypted data.
40
When you call send(), the data is encrypted and this class will then signal
41
for you to do the actual sending (as described above).
49
connect(&ssl, SIGNAL(readyRead()), SLOT(ssl_readyRead()));
50
connect(&ssl, SIGNAL(outgoingSSLDataReady()), SLOT(ssl_outgoingReady()));
52
When you are ready to begin negotiation, use begin(). You would probably
53
always do this immediately after you establish a socket connection. The
54
negotiation happens transparently, and if you send data before the SSL
55
channel is ready then it will be queued. So it is OK to do something
58
// slot that gets called when QSocket emits connected()
62
return; // error initializing ssl
64
// login (or something)
65
sock->send(array.data(), array.size());
68
Receiving data requires one extra step than before. Instead of
69
processing the socket data from your readyRead slot, you need to pass
70
the data on to SSLFilter. SSLFilter will then emit its own readyRead for
71
real data that you can process.
73
// slot that gets called when QSocket emits readyRead()
77
int size = sock->bytesAvailable();
79
sock->readBlock(buf.data(), size);
80
ssl.putIncomingSSLData(buf);
83
// slot that gets called when SSLFilter emits readyRead()
86
QByteArray buf = ssl->recv();
89
processIncomingData(buf);
92
Often, SSLFilter will want to send data. This will happen generally
93
after you call SSLFilter::send(), but OpenSSL may have other reasons
94
sometimes. It will emit outgoingSSLDataReady() when data is ready
97
void ssl_outgoingReady()
99
QByteArray buf = ssl->getOutgoingSSLData();
100
sock->writeBlock(buf.data(), buf.size());
103
To send data, use SSLFilter::send(). SSLFilter will perform the
104
encryption, and signal you to send the encrypted data when ready.
109
The OpenSSL library is used dynamically during runtime, and is thus not
110
required to compile or run your program. Be sure to use the isSupported()
111
function to make sure that the library was loaded properly.
113
On error, SSLFilter will emit error() and reset the class.
115
****************************************************************************/
117
class SSLFilter : public QObject
130
void send(const QByteArray &);
135
// pass incoming socket data to this function
136
void putIncomingSSLData(const QByteArray &);
137
// check/read outgoing socket data with this function
138
bool isOutgoingSSLData();
139
QByteArray getOutgoingSSLData();
143
void outgoingSSLDataReady();
150
enum { SSL_CONNECT, SSL_ACTIVE };
156
QByteArray sendQueue, recvQueue;
157
void processSendQueue();