1
//=============================================================================
4
// Creation date : Mon Feb 14 2010 19:36:12 CEST by Fabio Bas
6
// This file is part of the KVIrc irc client distribution
7
// Copyright (C) 2010 Fabio Bas (ctrlaltca at gmail dot com)
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.
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.
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.
23
//=============================================================================
29
#include "KviMemory.h"
31
#ifdef COMPILE_SSL_SUPPORT
33
#include <openssl/blowfish.h>
34
#include <openssl/bn.h>
35
#include <openssl/dh.h>
36
#include <openssl/err.h>
37
#include <KviNetUtils.h>
45
bool plainMethod(KviCString & szIn, KviCString & szOut, QByteArray & baNick, QByteArray & baPass)
49
int answerLen = 3 + (2 * baNick.size()) + baPass.size();
50
char * answer = (char *) KviMemory::allocate(answerLen);
51
char * answer2 = answer;
53
memcpy(answer, baNick.data(), baNick.size());
54
answer+=baNick.size();
58
memcpy(answer, baNick.data(), baNick.size());
59
answer+=baNick.size();
63
memcpy(answer, baPass.data(), baPass.size());
64
answer+=baPass.size();
68
szOut.bufferToBase64(answer2,answerLen);
69
KviMemory::free(answer2);
76
#ifdef COMPILE_SSL_SUPPORT
77
bool dh_blowfishMethod(KviCString & szIn, KviCString & szOut, QByteArray & baNick, QByteArray & baPass)
80
* The format of the auth token is quite complex; the server sends us 3 strings:
82
* g - a generator number, tipically 2 or 5 are used.
83
* y - the server-generated public key
84
* These 3 strings are null-terminated and codified as pascal strings (they are prefixed
85
* with a 16-bit lenght identifiedr in "network" big-endian order)
86
* Then, the 3 strings are concatenated and base-64 encoded.
92
unsigned char *secret = NULL, *pubKey = NULL;
95
int len = szIn.base64ToBuffer(&tmpBuf,false);
97
if(len < 7) return false;
100
size = ntohs(*(unsigned int*)tmpBuf);
103
if(size > len) return false;
105
if(!(dh->p = BN_bin2bn((unsigned char*) tmpBuf, size, NULL)))
112
size = ntohs(*(unsigned int*)tmpBuf);
115
if(size > len) return false;
117
if(!(dh->g = BN_bin2bn((unsigned char*) tmpBuf, size, NULL)))
124
size = ntohs(*(unsigned int*)tmpBuf);
127
if(size > len) return false;
129
// create our keys and extract shared secret
130
// note: any memory checking tool (as valgrind) will complain on this call. blame openssl
131
if(!DH_generate_key(dh))
134
secret=(unsigned char *) KviMemory::allocate(DH_size(dh));
135
// note: any memory checking tool (as valgrind) will complain on this call. blame openssl
136
if(-1 == (secretLen = DH_compute_key(secret, BN_bin2bn((unsigned char*) tmpBuf, size, NULL), dh)))
139
pKlen=BN_num_bytes(dh->pub_key);
140
pubKey = (unsigned char *) KviMemory::allocate(pKlen);
141
BN_bn2bin(dh->pub_key, pubKey);
143
//create crypto buffers
144
int passLen = baPass.size() + ((8 -( baPass.size() % 8)) % 8);
146
unsigned char *passIn = (unsigned char *) KviMemory::allocate(passLen);
147
unsigned char *passOut = (unsigned char *) KviMemory::allocate(passLen);
149
memset(passIn, 0, passLen);
150
memset(passOut, 0, passLen);
151
memcpy(passIn, baPass.data(), baPass.size());
153
// crypt our password
154
BF_set_key(&key, secretLen, secret);
156
for (passC=0; passC < passLen; passC += 8)
157
BF_ecb_encrypt(passIn + passC, passOut + passC, &key, BF_ENCRYPT);
160
* Build up the answer
161
* The format of the auth answer is quite complex, and formed by the byte concatenation of:
162
* 1) a 16 bit integer containing the byte length of our public key
164
* 3) our username (nickname), null-terminated
165
* 4) our password, crypted using blowfish in ecb mode and the dh secret as the blowfish key
166
* Then, the answer is to be base64 encoded.
169
int answerLen = 2 + pKlen + baNick.size() + 1 + passLen;
170
char * answer = (char *) malloc(answerLen);
171
char * answer2 = answer;
172
*((unsigned int *)answer) = htons(pKlen);
174
memcpy(answer, pubKey, pKlen);
176
memcpy(answer, baNick.data(), baNick.size());
177
answer+=baNick.size();
178
memset(answer, 0, 1);
180
memcpy(answer, passOut, passLen);
181
szOut.bufferToBase64(answer2,answerLen);
184
KviMemory::free(secret);
185
KviMemory::free(pubKey);
186
KviMemory::free(passIn);
187
KviMemory::free(passOut);
192
bool dh_blowfishMethod(KviCString & szIn, KviCString & szOut, QByteArray & baNick, QByteArray & baPass)