~ubuntu-branches/ubuntu/trusty/kvirc/trusty

« back to all changes in this revision

Viewing changes to src/kvilib/net/KviSSL.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Kai Wasserbäch, Kai Wasserbäch, Raúl Sánchez Siles
  • Date: 2011-02-12 10:40:21 UTC
  • mfrom: (14.1.3 sid)
  • Revision ID: james.westby@ubuntu.com-20110212104021-5mh4f75jlku20mnt
The combined "Twisted Experiment" and "Nocturnal Raid" release.

[ Kai Wasserbäch ]
* Synced to upstream's SVN revision 5467.
* debian/rules:
  - Added .PHONY line.
  - Resurrect -DMANUAL_REVISION, got lost somewhere and we build SVN
    revisions again.
  - Replace "-DWITH_NO_EMBEDDED_CODE=YES" with "-DWANT_CRYPTOPP=YES".
  - Change the remaining -DWITH/-DWITHOUT to the new -DWANT syntax.
* debian/control:
  - Removed DMUA, I'm a DD now.
  - Changed my e-mail address.
  - Removed unneeded relationships (no upgrades over two releases are
    supported).
  - Fix Suggests for kvirc-dbg.
  - kvirc-data: Make the "Suggests: kvirc" a Recommends, doesn't make much
    sense to install the -data package without the program.
* debian/source/local-options: Added with "unapply-patches".
* debian/kvirc.lintian-overrides: Updated to work for 4.1.1.
* debian/patches/21_make_shared-mime-info_B-D_superfluous.patch: Updated.
* debian/kvirc-data.install: Added .notifyrc.

[ Raúl Sánchez Siles ]
* Stating the right version where kvirc-data break and replace should happen.
* Fixing link to license file.
* Added French and Portuguese man pages.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
//=============================================================================
 
2
//
 
3
//   File : KviSSL.cpp
 
4
//   Creation date : Mon May 27 2002 21:36:12 CEST by Szymon Stefanek
 
5
//
 
6
//   This file is part of the KVIrc irc client distribution
 
7
//   Copyright (C) 2002-2010 Szymon Stefanek (pragma at kvirc dot net)
 
8
//
 
9
//   This program is FREE software. You can redistribute it and/or
 
10
//   modify it under the terms of the GNU General Public License
 
11
//   as published by the Free Software Foundation; either version 2
 
12
//   of the License, or (at your opinion) any later version.
 
13
//
 
14
//   This program is distributed in the HOPE that it will be USEFUL,
 
15
//   but WITHOUT ANY WARRANTY; without even the implied warranty of
 
16
//   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 
17
//   See the GNU General Public License for more details.
 
18
//
 
19
//   You should have received a copy of the GNU General Public License
 
20
//   along with this program. If not, write to the Free Software Foundation,
 
21
//   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 
22
//
 
23
//=============================================================================
 
24
 
 
25
 
 
26
 
 
27
#include "KviSSL.h"
 
28
#include "KviLocale.h"
 
29
 
 
30
#ifdef COMPILE_SSL_SUPPORT
 
31
 
 
32
#include "KviThread.h"
 
33
#include "KviMemory.h"
 
34
#include "KviMemory.h"
 
35
 
 
36
#include <openssl/asn1.h>
 
37
#include <openssl/err.h>
 
38
#include <openssl/dh.h>
 
39
 
 
40
#include <stdio.h>
 
41
 
 
42
#if !(defined(COMPILE_ON_WINDOWS) || defined(COMPILE_ON_MINGW))
 
43
        #include <signal.h>
 
44
#endif
 
45
 
 
46
static bool g_bSSLInitialized = false;
 
47
static KviMutex * g_pSSLMutex = 0;
 
48
 
 
49
 
 
50
static inline void my_ssl_lock()
 
51
{
 
52
        g_pSSLMutex->lock();
 
53
}
 
54
 
 
55
static inline void my_ssl_unlock()
 
56
{
 
57
        g_pSSLMutex->unlock();
 
58
}
 
59
 
 
60
 
 
61
// THIS PART OF OpenSSL SUCKS
 
62
 
 
63
static DH * dh_512 = 0;
 
64
static DH * dh_1024 = 0;
 
65
static DH * dh_2048 = 0;
 
66
static DH * dh_4096 = 0;
 
67
 
 
68
static unsigned char dh512_p[]={
 
69
        0x90,0x86,0xDD,0x06,0xE8,0x0F,0x10,0x86,0xF0,0x91,0xC5,0x55,
 
70
        0x4D,0x6B,0xAF,0x69,0x4F,0x01,0xED,0xF9,0x57,0x8F,0x3B,0xB8,
 
71
        0x9C,0x87,0xAE,0x85,0xC1,0xBF,0x57,0xA5,0xD5,0xBA,0x81,0x24,
 
72
        0xE7,0x99,0xE3,0xF6,0xCD,0xB4,0x41,0xB7,0x7F,0x6E,0x7B,0xB1,
 
73
        0xD2,0xF3,0xE9,0x0F,0xB9,0x0E,0x4D,0xEB,0x9D,0xD4,0xA9,0xE5,
 
74
        0x03,0x67,0xA7,0x27
 
75
};
 
76
static unsigned char dh512_g[]={ 0x05 };
 
77
 
 
78
static unsigned char dh1024_p[]={
 
79
        0xA5,0x4C,0xB9,0xB9,0xC4,0x35,0x88,0x68,0x9B,0x79,0x48,0x6C,
 
80
        0x21,0xA7,0x8E,0xE2,0x9C,0xAF,0x2F,0x04,0xBF,0x45,0xBC,0xF5,
 
81
        0xAB,0x35,0x86,0xC8,0xBB,0x9B,0x75,0x18,0x7C,0x9B,0xAB,0xE8,
 
82
        0x52,0x7F,0x57,0x3E,0xD8,0x65,0x7D,0x2B,0xE1,0x6D,0x3D,0xA5,
 
83
        0x32,0xE8,0xA0,0x2B,0x7A,0x58,0x6B,0x47,0x16,0x4E,0xB1,0xFC,
 
84
        0x09,0xB7,0x7C,0xC6,0xE9,0x6E,0xC7,0xC7,0xA1,0x42,0x0F,0x4B,
 
85
        0x43,0xFB,0x58,0xBA,0xC7,0x66,0xD6,0xCA,0x6B,0xC7,0x45,0x7C,
 
86
        0x99,0xE4,0x46,0x02,0x93,0x3F,0x28,0xD2,0xCE,0x0C,0x8A,0xDD,
 
87
        0x6A,0x22,0x2E,0xA9,0x9A,0xCA,0x16,0x48,0x4E,0x67,0x4C,0xE9,
 
88
        0xC8,0x54,0xCD,0x18,0xC9,0xF3,0x30,0x3A,0x74,0xAB,0xF9,0xAF,
 
89
        0xE4,0xA4,0x0D,0x56,0x62,0x28,0x07,0xBF
 
90
};
 
91
static unsigned char dh1024_g[]={ 0x05 };
 
92
 
 
93
static unsigned char dh2048_p[]={
 
94
        0xBF,0x67,0x7B,0x79,0xA5,0x22,0xD3,0xB5,0x0C,0x13,0xE6,0x92,
 
95
        0x54,0xFD,0x64,0xBF,0x57,0x25,0xBD,0x02,0x7C,0xFD,0x72,0x97,
 
96
        0x82,0xA4,0xA6,0x0A,0xB9,0xE6,0x4B,0xFA,0xBD,0xFA,0x71,0x8A,
 
97
        0x2E,0x36,0xF9,0x03,0x58,0x1B,0xB6,0x3A,0xFD,0x15,0xCC,0x87,
 
98
        0x5D,0x04,0xF7,0x45,0xE0,0xE2,0x34,0x7F,0x54,0x5F,0x5D,0x14,
 
99
        0xD3,0xCA,0x3E,0xFD,0x2A,0x92,0x10,0x89,0xA0,0xB0,0xB4,0xE5,
 
100
        0x80,0x05,0x13,0xBE,0xA3,0xD0,0x42,0x4B,0x98,0x44,0x54,0xB3,
 
101
        0xE0,0x23,0x26,0xF5,0x6B,0x0E,0x4D,0x2A,0x81,0xB2,0x8A,0x06,
 
102
        0xC8,0x00,0x9E,0xAB,0x1B,0x77,0xDC,0x87,0x9C,0x6C,0xD5,0xEE,
 
103
        0xB4,0xB4,0xDD,0xDA,0x3F,0x40,0xA3,0xFA,0xC1,0x1E,0xC0,0xA2,
 
104
        0x9E,0xB8,0xAC,0x31,0xE8,0x12,0x93,0x9C,0x71,0xF6,0xE7,0xF0,
 
105
        0x65,0x7F,0xA5,0x20,0xF7,0x49,0x3D,0xD6,0xF9,0xD3,0xF0,0x3F,
 
106
        0xB3,0xF0,0xD0,0x23,0x22,0x82,0xA5,0xDD,0xFB,0xD9,0x9C,0x7D,
 
107
        0xE7,0xA0,0x78,0xE8,0xF9,0x02,0x0C,0x2F,0x1D,0x52,0xC7,0x61,
 
108
        0xED,0xA0,0xC9,0x06,0x14,0xDF,0xE7,0xB1,0x1E,0x50,0x98,0x4F,
 
109
        0x10,0xB9,0x87,0x4C,0x1C,0x9C,0xB3,0xD2,0x98,0x23,0x7C,0x47,
 
110
        0xD2,0x3C,0xC5,0x29,0x65,0xC5,0x67,0x4E,0xC0,0x76,0x0F,0x43,
 
111
        0x27,0x28,0x89,0x69,0x30,0x7D,0x04,0xFD,0xF7,0x89,0xE5,0xD6,
 
112
        0xE6,0x97,0x7D,0xBB,0x54,0x5F,0xB7,0x94,0x1D,0xBC,0x82,0xAB,
 
113
        0x9A,0xF5,0x0A,0x0C,0x89,0x68,0xE7,0x0A,0x8C,0x2D,0x0D,0x82,
 
114
        0x44,0xA7,0xB8,0xF9,0x0B,0x8E,0xCB,0xA4,0x6A,0xA7,0xEC,0x5F,
 
115
        0x0A,0xF8,0x5F,0xE7
 
116
};
 
117
static unsigned char dh2048_g[]={ 0x05 };
 
118
 
 
119
static unsigned char dh4096_p[]={
 
120
        0xFA,0x14,0x72,0x52,0xC1,0x4D,0xE1,0x5A,0x49,0xD4,0xEF,0x09,
 
121
        0x2D,0xC0,0xA8,0xFD,0x55,0xAB,0xD7,0xD9,0x37,0x04,0x28,0x09,
 
122
        0xE2,0xE9,0x3E,0x77,0xE2,0xA1,0x7A,0x18,0xDD,0x46,0xA3,0x43,
 
123
        0x37,0x23,0x90,0x97,0xF3,0x0E,0xC9,0x03,0x50,0x7D,0x65,0xCF,
 
124
        0x78,0x62,0xA6,0x3A,0x62,0x22,0x83,0xA1,0x2F,0xFE,0x79,0xBA,
 
125
        0x35,0xFF,0x59,0xD8,0x1D,0x61,0xDD,0x1E,0x21,0x13,0x17,0xFE,
 
126
        0xCD,0x38,0x87,0x9E,0xF5,0x4F,0x79,0x10,0x61,0x8D,0xD4,0x22,
 
127
        0xF3,0x5A,0xED,0x5D,0xEA,0x21,0xE9,0x33,0x6B,0x48,0x12,0x0A,
 
128
        0x20,0x77,0xD4,0x25,0x60,0x61,0xDE,0xF6,0xB4,0x4F,0x1C,0x63,
 
129
        0x40,0x8B,0x3A,0x21,0x93,0x8B,0x79,0x53,0x51,0x2C,0xCA,0xB3,
 
130
        0x7B,0x29,0x56,0xA8,0xC7,0xF8,0xF4,0x7B,0x08,0x5E,0xA6,0xDC,
 
131
        0xA2,0x45,0x12,0x56,0xDD,0x41,0x92,0xF2,0xDD,0x5B,0x8F,0x23,
 
132
        0xF0,0xF3,0xEF,0xE4,0x3B,0x0A,0x44,0xDD,0xED,0x96,0x84,0xF1,
 
133
        0xA8,0x32,0x46,0xA3,0xDB,0x4A,0xBE,0x3D,0x45,0xBA,0x4E,0xF8,
 
134
        0x03,0xE5,0xDD,0x6B,0x59,0x0D,0x84,0x1E,0xCA,0x16,0x5A,0x8C,
 
135
        0xC8,0xDF,0x7C,0x54,0x44,0xC4,0x27,0xA7,0x3B,0x2A,0x97,0xCE,
 
136
        0xA3,0x7D,0x26,0x9C,0xAD,0xF4,0xC2,0xAC,0x37,0x4B,0xC3,0xAD,
 
137
        0x68,0x84,0x7F,0x99,0xA6,0x17,0xEF,0x6B,0x46,0x3A,0x7A,0x36,
 
138
        0x7A,0x11,0x43,0x92,0xAD,0xE9,0x9C,0xFB,0x44,0x6C,0x3D,0x82,
 
139
        0x49,0xCC,0x5C,0x6A,0x52,0x42,0xF8,0x42,0xFB,0x44,0xF9,0x39,
 
140
        0x73,0xFB,0x60,0x79,0x3B,0xC2,0x9E,0x0B,0xDC,0xD4,0xA6,0x67,
 
141
        0xF7,0x66,0x3F,0xFC,0x42,0x3B,0x1B,0xDB,0x4F,0x66,0xDC,0xA5,
 
142
        0x8F,0x66,0xF9,0xEA,0xC1,0xED,0x31,0xFB,0x48,0xA1,0x82,0x7D,
 
143
        0xF8,0xE0,0xCC,0xB1,0xC7,0x03,0xE4,0xF8,0xB3,0xFE,0xB7,0xA3,
 
144
        0x13,0x73,0xA6,0x7B,0xC1,0x0E,0x39,0xC7,0x94,0x48,0x26,0x00,
 
145
        0x85,0x79,0xFC,0x6F,0x7A,0xAF,0xC5,0x52,0x35,0x75,0xD7,0x75,
 
146
        0xA4,0x40,0xFA,0x14,0x74,0x61,0x16,0xF2,0xEB,0x67,0x11,0x6F,
 
147
        0x04,0x43,0x3D,0x11,0x14,0x4C,0xA7,0x94,0x2A,0x39,0xA1,0xC9,
 
148
        0x90,0xCF,0x83,0xC6,0xFF,0x02,0x8F,0xA3,0x2A,0xAC,0x26,0xDF,
 
149
        0x0B,0x8B,0xBE,0x64,0x4A,0xF1,0xA1,0xDC,0xEE,0xBA,0xC8,0x03,
 
150
        0x82,0xF6,0x62,0x2C,0x5D,0xB6,0xBB,0x13,0x19,0x6E,0x86,0xC5,
 
151
        0x5B,0x2B,0x5E,0x3A,0xF3,0xB3,0x28,0x6B,0x70,0x71,0x3A,0x8E,
 
152
        0xFF,0x5C,0x15,0xE6,0x02,0xA4,0xCE,0xED,0x59,0x56,0xCC,0x15,
 
153
        0x51,0x07,0x79,0x1A,0x0F,0x25,0x26,0x27,0x30,0xA9,0x15,0xB2,
 
154
        0xC8,0xD4,0x5C,0xCC,0x30,0xE8,0x1B,0xD8,0xD5,0x0F,0x19,0xA8,
 
155
        0x80,0xA4,0xC7,0x01,0xAA,0x8B,0xBA,0x53,0xBB,0x47,0xC2,0x1F,
 
156
        0x6B,0x54,0xB0,0x17,0x60,0xED,0x79,0x21,0x95,0xB6,0x05,0x84,
 
157
        0x37,0xC8,0x03,0xA4,0xDD,0xD1,0x06,0x69,0x8F,0x4C,0x39,0xE0,
 
158
        0xC8,0x5D,0x83,0x1D,0xBE,0x6A,0x9A,0x99,0xF3,0x9F,0x0B,0x45,
 
159
        0x29,0xD4,0xCB,0x29,0x66,0xEE,0x1E,0x7E,0x3D,0xD7,0x13,0x4E,
 
160
        0xDB,0x90,0x90,0x58,0xCB,0x5E,0x9B,0xCD,0x2E,0x2B,0x0F,0xA9,
 
161
        0x4E,0x78,0xAC,0x05,0x11,0x7F,0xE3,0x9E,0x27,0xD4,0x99,0xE1,
 
162
        0xB9,0xBD,0x78,0xE1,0x84,0x41,0xA0,0xDF
 
163
};
 
164
static unsigned char dh4096_g[]={ 0x02 };
 
165
 
 
166
static DH * my_get_dh(int keylength)
 
167
{
 
168
        DH * dh = 0;
 
169
        unsigned char * p = 0;
 
170
        unsigned char * g = 0;
 
171
        int sp = 0;
 
172
        int sg = 0;
 
173
        switch(keylength)
 
174
        {
 
175
                case 512:
 
176
                        dh = dh_512;
 
177
                        p  = dh512_p;
 
178
                        g  = dh512_g;
 
179
                        sp = sizeof(dh512_p);
 
180
                        sg = sizeof(dh512_g);
 
181
                break;
 
182
                case 1024:
 
183
                        dh = dh_1024;
 
184
                        p  = dh1024_p;
 
185
                        g  = dh1024_g;
 
186
                        sp = sizeof(dh1024_p);
 
187
                        sg = sizeof(dh1024_g);
 
188
                break;
 
189
                case 2048:
 
190
                        dh = dh_2048;
 
191
                        p  = dh2048_p;
 
192
                        g  = dh2048_g;
 
193
                        sp = sizeof(dh2048_p);
 
194
                        sg = sizeof(dh2048_g);
 
195
                break;
 
196
                case 4096:
 
197
                        dh = dh_4096;
 
198
                        p  = dh4096_p;
 
199
                        g  = dh4096_g;
 
200
                        sp = sizeof(dh4096_p);
 
201
                        sg = sizeof(dh4096_g);
 
202
                break;
 
203
                default:
 
204
                        // What the hell do you want from me ?
 
205
                        qDebug("OpenSSL is asking for a DH param with keylen %d: no way :D",keylength);
 
206
                break;
 
207
 
 
208
        }
 
209
 
 
210
        if(dh)return dh;
 
211
        dh = DH_new();
 
212
        if(!dh)return 0;
 
213
        dh->p=BN_bin2bn(p,sp,0);
 
214
        dh->g=BN_bin2bn(g,sg,0);
 
215
        if((dh->p == 0) || (dh->g == 0))
 
216
        {
 
217
                DH_free(dh);
 
218
                return 0;
 
219
        }
 
220
        return dh;
 
221
}
 
222
 
 
223
DH * my_ugly_dh_callback(SSL *, int, int keylength)
 
224
{
 
225
        my_ssl_lock();
 
226
        DH *dh = my_get_dh(keylength);
 
227
        my_ssl_unlock();
 
228
        return dh;
 
229
}
 
230
 
 
231
void KviSSL::globalInit()
 
232
{
 
233
        if(g_pSSLMutex)return;
 
234
        g_pSSLMutex = new KviMutex();
 
235
}
 
236
 
 
237
void KviSSL::globalDestroy()
 
238
{
 
239
        if(!g_pSSLMutex)return;
 
240
        if(dh_512)DH_free(dh_512);
 
241
        if(dh_1024)DH_free(dh_1024);
 
242
        if(dh_2048)DH_free(dh_2048);
 
243
        if(dh_4096)DH_free(dh_4096);
 
244
        globalSSLDestroy();
 
245
        delete g_pSSLMutex;
 
246
        g_pSSLMutex = 0;
 
247
}
 
248
 
 
249
void KviSSL::globalSSLInit()
 
250
{
 
251
        my_ssl_lock();
 
252
        if(!g_bSSLInitialized)
 
253
        {
 
254
                // FIXME: this should be done only if SSL is really needed
 
255
                SSL_library_init();
 
256
                SSL_load_error_strings();
 
257
                //needed to support SHA2 in < OpenSSL 0.9.8o and 1.0.0a
 
258
                OpenSSL_add_all_algorithms();
 
259
                g_bSSLInitialized = true;
 
260
        }
 
261
        my_ssl_unlock();
 
262
}
 
263
 
 
264
void KviSSL::globalSSLDestroy()
 
265
{
 
266
        my_ssl_lock();
 
267
        if(g_bSSLInitialized)
 
268
        {
 
269
                EVP_cleanup();
 
270
                g_bSSLInitialized = false;
 
271
        }
 
272
        my_ssl_unlock();
 
273
}
 
274
 
 
275
KviSSL::KviSSL()
 
276
{
 
277
        globalSSLInit();
 
278
        m_pSSL = 0;
 
279
        m_pSSLCtx = 0;
 
280
}
 
281
 
 
282
KviSSL::~KviSSL()
 
283
{
 
284
        shutdown();
 
285
}
 
286
 
 
287
#ifdef COMPILE_ON_WINDOWS
 
288
 
 
289
        // On windows we need to override new and delete operators
 
290
        // to ensure that always the right new/delete pair is called for an object instance
 
291
        // This bug is present in all the classes exported by a module that
 
292
        // can be instantiated/destroyed from external modules.
 
293
        // (this is a well known bug described in Q122675 of MSDN)
 
294
 
 
295
        void * KviSSL::operator new(size_t tSize)
 
296
        {
 
297
                return KviMemory::allocate(tSize);
 
298
        }
 
299
 
 
300
        void KviSSL::operator delete(void * p)
 
301
        {
 
302
                KviMemory::free(p);
 
303
        }
 
304
 
 
305
#endif
 
306
 
 
307
void KviSSL::shutdown()
 
308
{
 
309
        if(m_pSSL)
 
310
        {
 
311
                #if !(defined(COMPILE_ON_WINDOWS) || defined(COMPILE_ON_MINGW))
 
312
                //avoid to die on a SIGPIPE if the connection has close (SSL_shutdown can call send())
 
313
                //see bug #440
 
314
                signal( SIGPIPE, SIG_IGN );
 
315
                // At least attempt to shutdown the connection gracefully
 
316
                SSL_shutdown(m_pSSL);
 
317
                //restore normal SIGPIPE behaviour.
 
318
                signal( SIGPIPE, SIG_DFL );
 
319
                #else
 
320
                // At least attempt to shutdown the connection gracefully
 
321
                SSL_shutdown(m_pSSL);
 
322
                #endif
 
323
                SSL_free(m_pSSL);
 
324
                m_pSSL = 0;
 
325
        }
 
326
        if(m_pSSLCtx)
 
327
        {
 
328
                SSL_CTX_free(m_pSSLCtx);
 
329
                m_pSSLCtx = 0;
 
330
        }
 
331
}
 
332
 
 
333
/**
 
334
 * Used only during passive (server) mode
 
335
 * Check the client certificate, always valid, even if it not exists
 
336
 */
 
337
int verify_clientCallback(int, X509_STORE_CTX *)
 
338
{
 
339
        //int preverify_ok, X509_STORE_CTX *x509_ctx
 
340
        // From man page: If verify_callback returns 1, the verification process is continued. If verify_callback always returns 1,
 
341
        // the TLS/SSL handshake will not be terminated with respect to verification failures and the connection will be established.
 
342
        return 1;
 
343
}
 
344
 
 
345
bool KviSSL::initContext(Method m)
 
346
{
 
347
        if(m_pSSL)return false;
 
348
        m_pSSLCtx = SSL_CTX_new(m == Client ? SSLv23_client_method() : SSLv23_server_method());
 
349
        if(!m_pSSLCtx)return false;
 
350
 
 
351
        if (m == Server)
 
352
        {
 
353
                // we have to request the peer certificate, else only the client can see the peer identity, not the server
 
354
                SSL_CTX_set_verify(m_pSSLCtx, SSL_VERIFY_PEER, verify_clientCallback);
 
355
        } 
 
356
        
 
357
        // we want all ciphers to be available here, except insecure ones, orderer by strength;
 
358
        // ADH are moved to the end since they are less secure, but they don't need a certificate
 
359
        // (so we can use secure dcc without a cert)
 
360
        // NOTE: see bug ticket #155
 
361
        SSL_CTX_set_cipher_list(m_pSSLCtx,"ALL:!eNULL:!EXP:!SSLv2:+ADH@STRENGTH");
 
362
        SSL_CTX_set_tmp_dh_callback(m_pSSLCtx,my_ugly_dh_callback);
 
363
        return true;
 
364
}
 
365
 
 
366
bool KviSSL::initSocket(kvi_socket_t fd)
 
367
{
 
368
        if(!m_pSSLCtx)return false;
 
369
        m_pSSL = SSL_new(m_pSSLCtx);
 
370
        if(!m_pSSL)return false;
 
371
        if(!SSL_set_fd(m_pSSL,fd))return false;
 
372
        return true;
 
373
 
 
374
}
 
375
 
 
376
static int cb(char *buf, int size, int, void *u)
 
377
{
 
378
        KviCString * p = (KviCString *)u;
 
379
        int len = p->len();
 
380
        if(len >= size)return 0;
 
381
        KviMemory::move(buf,p->ptr(),len + 1);
 
382
//      qDebug("PASS REQYESTED: %s",p->ptr());
 
383
        return len;
 
384
}
 
385
 
 
386
KviSSL::Result KviSSL::useCertificateFile(const char * cert,const char * pass)
 
387
{
 
388
        if(!m_pSSLCtx)return NotInitialized;
 
389
        m_szPass = pass;
 
390
        if(m_szPass.len() < 4)m_szPass.append("xxxx");
 
391
        X509 * x509 = 0;
 
392
 
 
393
        FILE * f = fopen(cert,"r");
 
394
        if(!f)
 
395
                return FileIoError;
 
396
 
 
397
//      qDebug("READING CERTIFICATE %s",cert);
 
398
        if(PEM_read_X509(f,&x509,cb,&m_szPass))
 
399
        {
 
400
                if(!SSL_CTX_use_certificate(m_pSSLCtx,x509))
 
401
                {
 
402
                        X509_free(x509);
 
403
                        fclose(f);
 
404
                        return SSLError;
 
405
                }
 
406
                X509_free(x509);
 
407
        }
 
408
 
 
409
        fclose(f);
 
410
        return Success;
 
411
}
 
412
 
 
413
 
 
414
KviSSL::Result KviSSL::usePrivateKeyFile(const char * key,const char * pass)
 
415
{
 
416
        if(!m_pSSLCtx)return NotInitialized;
 
417
        m_szPass = pass;
 
418
        if(m_szPass.len() < 4)m_szPass.append("xxxx");
 
419
 
 
420
        EVP_PKEY * k = 0;
 
421
 
 
422
        FILE * f = fopen(key,"r");
 
423
        if(!f)
 
424
                return FileIoError;
 
425
 
 
426
//      qDebug("READING KEY %s",key);
 
427
        if(PEM_read_PrivateKey(f,&k,cb,&m_szPass))
 
428
        {
 
429
                if(!SSL_CTX_use_PrivateKey(m_pSSLCtx,k))
 
430
                {
 
431
                        EVP_PKEY_free(k);
 
432
                        fclose(f);
 
433
                        return SSLError;
 
434
                }
 
435
                EVP_PKEY_free(k);
 
436
        }
 
437
 
 
438
        fclose(f);
 
439
        return Success;
 
440
}
 
441
 
 
442
unsigned long KviSSL::getLastError(bool bPeek)
 
443
{
 
444
        return bPeek ? ERR_peek_error() : ERR_get_error();
 
445
}
 
446
 
 
447
bool KviSSL::getLastErrorString(KviCString &buffer,bool bPeek)
 
448
{
 
449
        unsigned long uErr = getLastError(bPeek);
 
450
        if(uErr != 0)
 
451
        {
 
452
                const char * err = ERR_reason_error_string(uErr);
 
453
                buffer = err ? err : "Unknown error";
 
454
                return true;
 
455
        }
 
456
        return false;
 
457
}
 
458
 
 
459
KviSSL::Result KviSSL::connect()
 
460
{
 
461
        if(!m_pSSL)return NotInitialized;
 
462
        int ret = SSL_connect(m_pSSL);
 
463
        return connectOrAcceptError(ret);
 
464
}
 
465
 
 
466
KviSSL::Result KviSSL::accept()
 
467
{
 
468
        if(!m_pSSL)return NotInitialized;
 
469
        int ret = SSL_accept(m_pSSL);
 
470
        return connectOrAcceptError(ret);
 
471
}
 
472
 
 
473
KviSSL::Result KviSSL::connectOrAcceptError(int ret)
 
474
{
 
475
        switch(SSL_get_error(m_pSSL,ret))
 
476
        {
 
477
                case SSL_ERROR_NONE: return Success; break;
 
478
                case SSL_ERROR_WANT_READ: return WantRead; break;
 
479
                case SSL_ERROR_WANT_WRITE: return WantWrite; break;
 
480
                case SSL_ERROR_ZERO_RETURN: return RemoteEndClosedConnection; break;
 
481
                case SSL_ERROR_WANT_X509_LOOKUP: return ObscureError; break;
 
482
                case SSL_ERROR_SYSCALL:
 
483
                {
 
484
                        if(getLastError(true) != 0)return SSLError;
 
485
                        if(ret == 0)return RemoteEndClosedConnection;
 
486
                        return SyscallError;
 
487
                }
 
488
                break;
 
489
                case SSL_ERROR_SSL: return SSLError; break;
 
490
                default: return UnknownError; break;
 
491
        }
 
492
        return UnknownError;
 
493
}
 
494
 
 
495
int KviSSL::read(char * buffer,int len)
 
496
{
 
497
//      if(!m_pSSL)return -1;
 
498
        return SSL_read(m_pSSL,buffer,len);
 
499
}
 
500
int KviSSL::write(const char * buffer,int len)
 
501
{
 
502
//      if(!m_pSSL)return -1;
 
503
        return SSL_write(m_pSSL,buffer,len);
 
504
}
 
505
 
 
506
KviSSL::Result KviSSL::getProtocolError(int ret)
 
507
{
 
508
        if(!m_pSSL)return NotInitialized;
 
509
        switch(SSL_get_error(m_pSSL,ret))
 
510
        {
 
511
                case SSL_ERROR_NONE: return Success; break;
 
512
                case SSL_ERROR_WANT_READ: return WantRead; break;
 
513
                case SSL_ERROR_WANT_WRITE: return WantWrite; break;
 
514
                case SSL_ERROR_ZERO_RETURN: return ZeroReturn; break;
 
515
                case SSL_ERROR_WANT_X509_LOOKUP: return ObscureError; break;
 
516
                case SSL_ERROR_SYSCALL: return SyscallError; break;
 
517
                case SSL_ERROR_SSL: return SSLError; break;
 
518
                default: return UnknownError; break;
 
519
        }
 
520
        return UnknownError;
 
521
}
 
522
 
 
523
KviSSLCertificate * KviSSL::getPeerCertificate()
 
524
{
 
525
        if(!m_pSSL)return 0;
 
526
        X509 * x509 = SSL_get_peer_certificate(m_pSSL);
 
527
        if(!x509)return 0;
 
528
        return new KviSSLCertificate(x509);
 
529
}
 
530
 
 
531
KviSSLCertificate * KviSSL::getLocalCertificate()
 
532
{
 
533
        if(!m_pSSL)return 0;
 
534
        X509 * x509 = SSL_get_certificate(m_pSSL);
 
535
        if(!x509)return 0;
 
536
        return new KviSSLCertificate(x509);
 
537
}
 
538
 
 
539
KviSSLCipherInfo * KviSSL::getCurrentCipherInfo()
 
540
{
 
541
        if(!m_pSSL)return 0;
 
542
#if OPENSSL_VERSION_NUMBER >= 0x10000000L
 
543
        const SSL_CIPHER * c = SSL_get_current_cipher(m_pSSL);
 
544
#else
 
545
        SSL_CIPHER * c = SSL_get_current_cipher(m_pSSL);
 
546
#endif
 
547
        if(!c)return 0;
 
548
        return new KviSSLCipherInfo(c);
 
549
}
 
550
 
 
551
 
 
552
 
 
553
KviSSLCertificate::KviSSLCertificate(X509 * x509)
 
554
{
 
555
        m_pSubject = new KviPointerHashTable<const char *,KviCString>(17);
 
556
        m_pSubject->setAutoDelete(true);
 
557
        m_pIssuer = new KviPointerHashTable<const char *,KviCString>(17);
 
558
        m_pIssuer->setAutoDelete(true);
 
559
        m_pX509 = 0;
 
560
        setX509(x509);
 
561
}
 
562
 
 
563
KviSSLCertificate::~KviSSLCertificate()
 
564
{
 
565
        X509_free(m_pX509);
 
566
        delete m_pSubject;
 
567
        delete m_pIssuer;
 
568
}
 
569
 
 
570
const char * KviSSLCertificate::getX509Base64()
 
571
{
 
572
        BUF_MEM *bptr;
 
573
        BIO* mem = BIO_new(BIO_s_mem());
 
574
        PEM_write_bio_X509(mem, m_pX509);
 
575
        int iLen = BIO_get_mem_data(mem, &bptr);
 
576
        char * szTmp = (char *) KviMemory::allocate(iLen+1);
 
577
        KviMemory::copy(szTmp, bptr, iLen);
 
578
        *(szTmp+iLen) = '\0';
 
579
        BIO_free_all(mem);
 
580
        return szTmp;
 
581
}
 
582
 
 
583
#ifdef COMPILE_ON_WINDOWS
 
584
 
 
585
        // On windows we need to override new and delete operators
 
586
        // to ensure that always the right new/delete pair is called for an object instance
 
587
        // This bug is present in all the classes exported by a module that
 
588
        // can be instantiated/destroyed from external modules.
 
589
        // (this is a well known bug described in Q122675 of MSDN)
 
590
 
 
591
        void * KviSSLCertificate::operator new(size_t tSize)
 
592
        {
 
593
                return KviMemory::allocate(tSize);
 
594
        }
 
595
 
 
596
        void KviSSLCertificate::operator delete(void * p)
 
597
        {
 
598
                KviMemory::free(p);
 
599
        }
 
600
 
 
601
#endif
 
602
 
 
603
void KviSSLCertificate::setX509(X509 * x509)
 
604
{
 
605
        if(m_pX509)X509_free(m_pX509);
 
606
        m_pX509 = x509;
 
607
        m_iVersion = X509_get_version(x509);
 
608
        extractSubject();
 
609
        extractIssuer();
 
610
        extractPubKeyInfo();
 
611
        extractSerialNumber();
 
612
        extractSignature();
 
613
}
 
614
 
 
615
bool KviSSLCertificate::fingerprintIsValid()
 
616
{
 
617
        if(!m_pX509)
 
618
                return false;
 
619
 
 
620
        EVP_PKEY * pkey = X509_get_pubkey(m_pX509);
 
621
        int rv = X509_verify(m_pX509, pkey);
 
622
        
 
623
        // careful: https://support.ntp.org/bugs/show_bug.cgi?id=1127
 
624
        // quote: X509_verify is a call to ASN1_item_verify which can return both 0 and -1 for error cases.
 
625
        // In particular it can return -1 when the message digest type is not known, or memory allocation failed.
 
626
        return (rv > 0);
 
627
}
 
628
 
 
629
int KviSSLCertificate::fingerprintDigestId()
 
630
{
 
631
        if(!m_pX509)
 
632
                return -1;
 
633
        
 
634
        int NID = OBJ_obj2nid(m_pX509->sig_alg->algorithm);
 
635
        if (NID == NID_undef) 
 
636
        {
 
637
                // unknow digest function: it means the signature can't be verified: the certificate can't be trusted
 
638
                return 0;
 
639
        }
 
640
        
 
641
        const EVP_MD * mdType = NULL;
 
642
        mdType = EVP_get_digestbyname(OBJ_nid2sn(NID));
 
643
        
 
644
        if (mdType == NULL) 
 
645
        {
 
646
                // Unknown digest
 
647
                return 0;
 
648
        }
 
649
        
 
650
        return mdType->type;
 
651
}
 
652
 
 
653
const char * KviSSLCertificate::fingerprintDigestStr()
 
654
{
 
655
        int iDigestType = fingerprintDigestId();
 
656
        
 
657
        if(iDigestType == 0)
 
658
                return "";
 
659
        
 
660
        return OBJ_nid2ln(iDigestType);
 
661
}
 
662
 
 
663
const char * KviSSLCertificate::fingerprintContents(QString digestName)
 
664
{
 
665
        unsigned char bufferData[EVP_MAX_MD_SIZE];
 
666
        unsigned int bufferLen = 0;
 
667
        const char * pDigestName;
 
668
        if (digestName.isEmpty())
 
669
        {
 
670
                // use the one used to create the signature
 
671
                pDigestName = OBJ_nid2sn(fingerprintDigestId());
 
672
        } else {
 
673
                pDigestName = digestName.toUtf8().data();
 
674
        }
 
675
        
 
676
        if(getFingerprint(bufferData, &bufferLen, pDigestName) != 0)
 
677
                return "";
 
678
        
 
679
        QByteArray digestByteArray = QByteArray::fromRawData((char *) bufferData, bufferLen);
 
680
        return digestByteArray.toHex().data();
 
681
}
 
682
 
 
683
int KviSSLCertificate::getFingerprint(unsigned char * bufferData, unsigned int * bufferLen, const char * digestName)
 
684
{
 
685
        //TODO if in the future we will want to check the return value, ensure this
 
686
        // doesn't collide with the one from openssl
 
687
        if(!m_pX509)
 
688
                return -99;
 
689
        
 
690
        const EVP_MD * mdType = NULL;
 
691
        mdType = EVP_get_digestbyname(digestName);
 
692
        
 
693
        if (mdType == NULL) 
 
694
        {
 
695
                // Unknown digest
 
696
                return -98;
 
697
        }
 
698
        
 
699
        if (!X509_digest(m_pX509, mdType, bufferData, bufferLen))
 
700
        {
 
701
                return -97;
 
702
        }
 
703
        
 
704
        return 0;
 
705
}
 
706
 
 
707
void KviSSLCertificate::extractSubject()
 
708
{
 
709
        char buffer[1024];
 
710
        char * t = X509_NAME_oneline(X509_get_subject_name(m_pX509),buffer,1024);
 
711
        if (!t)return;
 
712
        m_pSubject->clear();
 
713
        splitX509String(m_pSubject,t);
 
714
}
 
715
 
 
716
void KviSSLCertificate::extractIssuer()
 
717
{
 
718
        char buffer[1024];
 
719
        char * t = X509_NAME_oneline(X509_get_issuer_name(m_pX509),buffer,1024);
 
720
        if (!t)return;
 
721
        m_pIssuer->clear();
 
722
        splitX509String(m_pIssuer,t);
 
723
}
 
724
 
 
725
void KviSSLCertificate::splitX509String(KviPointerHashTable<const char *,KviCString> * dict,const char * t)
 
726
{
 
727
        KviCString buf = t;
 
728
        int cnt;
 
729
        KviCString ** arr = buf.splitToArray('/',50,&cnt);
 
730
        if(arr)
 
731
        {
 
732
                if(cnt > 0)
 
733
                {
 
734
                        for(int i=0;i<cnt;i++)
 
735
                        {
 
736
                                int idx = arr[i]->findFirstIdx('=');
 
737
                                if(idx != -1)
 
738
                                {
 
739
                                        KviCString szTok = arr[i]->left(idx);
 
740
                                        arr[i]->cutLeft(idx + 1);
 
741
                                        if(szTok.hasData() && arr[i]->hasData())
 
742
                                        {
 
743
                                                dict->replace(szTok.ptr(),new KviCString(arr[i]->ptr()));
 
744
                                        }
 
745
                                }
 
746
                        }
 
747
                }
 
748
 
 
749
                KviCString::freeArray(arr);
 
750
        }
 
751
}
 
752
 
 
753
 
 
754
const char * KviSSLCertificate::dictEntry(KviPointerHashTable<const char *,KviCString> * dict,const char * entry)
 
755
{
 
756
        KviCString * t = dict->find(entry);
 
757
        if(!t)return __tr("Unknown");
 
758
        return t->ptr();
 
759
}
 
760
 
 
761
 
 
762
/*
 
763
void KviSSLCertificate::getPKeyType(int type,KviCString &buffer)
 
764
{
 
765
        switch(type)
 
766
        {
 
767
#ifndef NO_RSA
 
768
                case EVP_PKEY_RSA:   buffer = "RSA";     break;
 
769
#endif
 
770
#ifndef NO_DSA
 
771
                case EVP_PKEY_DSA:   buffer = "DSA";     break;
 
772
#endif
 
773
#ifndef NO_DH
 
774
                case EVP_PKEY_DH:    buffer = "DH";      break;
 
775
#endif
 
776
                case EVP_PKEY_NONE:  buffer = "NONE";    break;
 
777
        }
 
778
}
 
779
*/
 
780
 
 
781
void KviSSLCertificate::extractPubKeyInfo()
 
782
{
 
783
        EVP_PKEY *p = X509_get_pubkey(m_pX509);
 
784
        if(p)
 
785
        {
 
786
                m_iPubKeyBits = EVP_PKEY_bits(p);
 
787
                m_szPubKeyType = (p->type == NID_undef) ? __tr("Unknown") : OBJ_nid2ln(p->type);
 
788
//              getPKeyType(p->type,m_szPubKeyType);
 
789
        } else {
 
790
                m_iPubKeyBits = 0;
 
791
                m_szPubKeyType = "None";
 
792
        }
 
793
 
 
794
}
 
795
 
 
796
void KviSSLCertificate::extractSerialNumber()
 
797
{
 
798
        ASN1_INTEGER * i = X509_get_serialNumber(m_pX509);
 
799
        if(i)m_iSerialNumber = ASN1_INTEGER_get(i);
 
800
        else m_iSerialNumber = -1;
 
801
}
 
802
 
 
803
void KviSSLCertificate::extractSignature()
 
804
{
 
805
        static char hexdigits[] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
 
806
 
 
807
        //getPKeyType(X509_get_signature_type(m_pX509),m_szSignatureType);
 
808
 
 
809
        int i = OBJ_obj2nid(m_pX509->sig_alg->algorithm);
 
810
        m_szSignatureType = (i == NID_undef) ? __tr("Unknown") : OBJ_nid2ln(i);
 
811
 
 
812
        m_szSignatureContents = "";
 
813
 
 
814
        for(i = 0;i < m_pX509->signature->length;i++)
 
815
        {
 
816
                if(m_szSignatureContents.hasData())m_szSignatureContents.append(":");
 
817
                m_szSignatureContents.append(hexdigits[(m_pX509->signature->data[i] & 0xf0) >> 4]);
 
818
                m_szSignatureContents.append(hexdigits[(m_pX509->signature->data[i] & 0x0f)]);
 
819
        }
 
820
}
 
821
 
 
822
/*
 
823
const char * KviSSLCertificate::verify()
 
824
{
 
825
 
 
826
}
 
827
*/
 
828
 
 
829
#if OPENSSL_VERSION_NUMBER >= 0x10000000L
 
830
KviSSLCipherInfo::KviSSLCipherInfo(const SSL_CIPHER * c)
 
831
#else
 
832
KviSSLCipherInfo::KviSSLCipherInfo(SSL_CIPHER * c)
 
833
#endif
 
834
{
 
835
        m_szVersion = SSL_CIPHER_get_version(c);
 
836
        m_iNumBitsUsed = SSL_CIPHER_get_bits(c,&m_iNumBits);
 
837
        m_szName = SSL_CIPHER_get_name(c);
 
838
        char buf[1024];
 
839
        m_szDescription = SSL_CIPHER_description(c,buf,1024);
 
840
}
 
841
 
 
842
KviSSLCipherInfo::~KviSSLCipherInfo()
 
843
{
 
844
}
 
845
 
 
846
#ifdef COMPILE_ON_WINDOWS
 
847
 
 
848
        // On windows we need to override new and delete operators
 
849
        // to ensure that always the right new/delete pair is called for an object instance
 
850
        // This bug is present in all the classes exported by a module that
 
851
        // can be instantiated/destroyed from external modules.
 
852
        // (this is a well known bug described in Q122675 of MSDN)
 
853
 
 
854
        void * KviSSLCipherInfo::operator new(size_t tSize)
 
855
        {
 
856
                return KviMemory::allocate(tSize);
 
857
        }
 
858
 
 
859
        void KviSSLCipherInfo::operator delete(void * p)
 
860
        {
 
861
                KviMemory::free(p);
 
862
        }
 
863
 
 
864
#endif
 
865
 
 
866
#endif //COMPILE_SSL_SUPPORT