00001 #ifndef SST_KEY_H
00002 #define SST_KEY_H
00003
00004 #include <QHash>
00005 #include <QPointer>
00006
00007 #include <openssl/dh.h>
00008
00009 #include "sock.h"
00010 #include "timer.h"
00011
00012
00013 namespace SST {
00014
00015
00016
00017
00018
00019
00020
00021
00022 #define KEYMETH_NONE 0x0001 // No security at all
00023 #define KEYMETH_CHK 0x0002 // Weak 32-bit keyed checksum
00024 #define KEYMETH_SHA256 0x0010 // HMAC-SHA256 auth, DH key agreement
00025 #define KEYMETH_AES 0x0020 // AES enc, HMAC-SHA256 auth, DH
00026 #define KEYMETH_DEFAULT KEYMETH_AES // Secure by default
00027
00028
00029
00030 #define KEYCHUNK_NI 0x0001 // Multi-cyphersuite initiator nonce
00031 #define KEYCHUNK_JFDH_R0 0x0010 // DH-based JFK key agreement
00032 #define KEYCHUNK_JFDH_I1 0x0011
00033 #define KEYCHUNK_JFDH_R1 0x0012
00034 #define KEYCHUNK_JFDH_I2 0x0013
00035 #define KEYCHUNK_JFDH_R2 0x0014
00036
00037
00038 class Host;
00039 class Flow;
00040 class KeyInitiator;
00041 class KeyResponder;
00042 class KeyHostState;
00043 class DHKey;
00044
00045 class KeyChunkChkI1Data;
00046 class KeyChunkChkR1Data;
00047 class KeyChunkDhI1Data;
00048 class KeyChunkDhR1Data;
00049 class KeyChunkDhI2Data;
00050 class KeyChunkDhR2Data;
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061 class KeyInitiator : public QObject
00062 {
00063 Q_OBJECT
00064 friend class KeyResponder;
00065
00066 enum State {
00067 I1,
00068 I2,
00069 Done
00070 };
00071
00072
00073 Host *const h;
00074 Flow *const fl;
00075 SocketEndpoint sepr;
00076 QByteArray idr;
00077 QByteArray ulpi;
00078 const quint32 magic;
00079 quint32 methods;
00080
00081
00083
00084 quint32 chkkey;
00085 QByteArray cookie;
00086
00087
00089
00090 quint8 dhgroup;
00091 quint8 keylen;
00092
00093
00094 State state;
00095 QByteArray ni, nhi;
00096 QByteArray dhi;
00097
00098
00099 QByteArray nr;
00100 QByteArray dhr;
00101 QByteArray hhkr;
00102 QByteArray master;
00103 QByteArray encidi;
00104
00105
00106 Timer txtimer;
00107
00108
00109 public:
00110
00111
00112
00113
00114
00115
00116
00117 KeyInitiator(Flow *flow, quint32 magic,
00118 const QByteArray &idr = QByteArray(),
00119 quint8 dhgroup = 0);
00120 ~KeyInitiator();
00121
00122 inline Host *host() { return h; }
00123
00124 inline Flow *flow() { return fl; }
00125 inline bool isDone() { return state == Done; }
00126
00127 inline SocketEndpoint remoteEndpoint() { return sepr; }
00128
00129
00130
00131
00132
00133 inline QByteArray info() { return ulpi; }
00134 inline void setInfo(const QByteArray &info) { ulpi = info; }
00135
00136 signals:
00137 void completed(bool success);
00138
00139 private:
00140 void sendI1();
00141 void sendDhI2();
00142
00143
00144 static void gotR0(Host *h, const Endpoint &src);
00145 static void gotChkR1(Host *h, KeyChunkChkR1Data &r1,
00146 const SocketEndpoint &ep);
00147 static void gotDhR1(Host *h, KeyChunkDhR1Data &r1);
00148 static void gotDhR2(Host *h, KeyChunkDhR2Data &r2);
00149
00150 private slots:
00151 void retransmit(bool fail);
00152 };
00153
00154
00155
00156 class KeyResponder : public SocketReceiver
00157 {
00158 friend class KeyInitiator;
00159
00160 private:
00161 Host *const h;
00162
00163 public:
00164
00165
00166
00167 KeyResponder(Host *host, quint32 magic, QObject *parent = NULL);
00168
00169 inline Host *host() { return h; }
00170
00171
00172 void receive(QByteArray &msg, XdrStream &rs,
00173 const SocketEndpoint &src);
00174
00175
00176
00177
00178
00179 void sendR0(const Endpoint &dst);
00180
00181
00182 protected:
00183
00184
00185
00186 virtual bool checkInitiator(const SocketEndpoint &epi,
00187 const QByteArray &eidi, const QByteArray &ulpi);
00188
00189
00190
00191
00192
00193
00194
00195 virtual Flow *newFlow(const SocketEndpoint &epi,
00196 const QByteArray &eidi, const QByteArray &ulpi,
00197 QByteArray &ulpr) = 0;
00198
00199
00200 private:
00201 void gotChkI1(KeyChunkChkI1Data &i1, const SocketEndpoint &src);
00202
00203 void gotDhI1(KeyChunkDhI1Data &i1, const SocketEndpoint &src);
00204 void handleDhI1(quint8 dhgroup, const QByteArray &nhi,
00205 QByteArray &pki, const SocketEndpoint &src);
00206 void gotDhI2(KeyChunkDhI2Data &i2, const SocketEndpoint &src);
00207
00208 static QByteArray calcDhCookie(DHKey *hk,
00209 const QByteArray &nr, const QByteArray &nhi,
00210 const Endpoint &src);
00211 };
00212
00213
00214
00215 typedef QPair<Endpoint, quint32> KeyEpChk;
00216
00217 class KeyHostState
00218 {
00219 friend class KeyInitiator;
00220
00221 private:
00222
00223 QHash<KeyEpChk, KeyInitiator*> initchks;
00224
00225
00226 QHash<QByteArray, KeyInitiator*> initnhis;
00227
00228
00229 QHash<Endpoint, KeyInitiator*> initeps;
00230
00231 public:
00232 };
00233
00234
00235 }
00236
00237 #endif // SST_KEY_H