View difference between Paste ID: K8zvJ89v and NDVtfcVG
SHOW: | | - or go back to the newest paste.
1
#include "znc/main.h"
2
#include "znc/User.h"
3
#include "znc/Nick.h"
4
#include "znc/Modules.h"
5
#include "znc/Chan.h"
6
#include "znc/IRCNetwork.h"
7
8
#include <string.h>
9
using std::pair;
10
using std::map;
11
12
#include <netinet/in.h>
13
14
#include <openssl/opensslv.h>
15
#include <openssl/blowfish.h>
16
17
#define REQUIRESSL	1
18
19
#if (OPENSSL_VERSION_NUMBER < 0x0090800f)
20
#error "We require openssl >= 0.9.8"
21
#endif
22
23
/*
24
    Public Base64 conversion tables
25
*/
26
unsigned char B64ABC[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
27
unsigned char b64buf[256];
28
29
30
/*
31
    void initb64();
32
    Initializes the base64->base16 conversion tab.
33
    Call this function once when your program starts.
34
    and always after your B64 table has been changed.
35
*/
36
void initb64(){
37
    unsigned int i;
38
    for (i=0; i<256; i++) b64buf[i]=0x00;
39
    for (i=0; i<64; i++) b64buf[(B64ABC[i])]=i;
40
}
41
42
/*
43
   int b64toh(lpBase64String, lpDestinationBuffer);
44
   Converts base64 string b to hexnumber d.
45
   Returns size of hexnumber in bytes.
46
*/
47
int b64toh(char *b, char *d){
48
    int i,k,l;
49
50
    l=strlen(b);
51
    if (l<2) return 0;
52
    for (i=l-1;i>-1;i--){
53
        if (b64buf[(unsigned char)(b[i])]==0) l--;
54
        else break;
55
    }
56
57
    if (l<2) return 0;
58
    i=0, k=0;
59
    while (1) {
60
        i++;
61
        if (k+1<l) d[i-1]=((b64buf[(unsigned char)(b[k])])<<2);
62
        else break;
63
        k++;
64
        if (k<l) d[i-1]|=((b64buf[(unsigned char)(b[k])])>>4);
65
        else break;
66
        i++;
67
        if (k+1<l) d[i-1]=((b64buf[(unsigned char)(b[k])])<<4);
68
        else break;
69
        k++;
70
        if (k<l) d[i-1]|=((b64buf[(unsigned char)(b[k])])>>2);
71
        else break;
72
        i++;
73
        if (k+1<l) d[i-1]=((b64buf[(unsigned char)(b[k])])<<6);
74
        else break;
75
        k++;
76
        if (k<l) d[i-1]|=(b64buf[(unsigned char)(b[k])]);
77
        else break;
78
        k++;
79
    }
80
    return i-1;
81
}
82
83
/*
84
   int htob64(lpHexNumber, lpDestinationBuffer);
85
   Converts hexnumber h (with length l bytes) to base64 string d.
86
   Returns length of base64 string.
87
*/
88
int htob64(char *h, char *d, unsigned int l){
89
    unsigned int i,j,k;
90
    unsigned char m,t;
91
92
    if (!l) return 0;
93
    l<<=3;                              // no. bits
94
    m=0x80;
95
    for (i=0,j=0,k=0,t=0; i<l; i++){
96
        if (h[(i>>3)]&m) t|=1;
97
        j++;
98
        if (!(m>>=1)) m=0x80;
99
        if (!(j%6)) {
100
            d[k]=B64ABC[t];
101
            t&=0;
102
            k++;
103
        }
104
        t<<=1;
105
    }
106
    m=5-(j%6);
107
    t<<=m;
108
    if (m) {
109
        d[k]=B64ABC[t];
110
        k++;
111
    }
112
    d[k]&=0;
113
    return strlen(d);
114
}
115
116
unsigned char B64[]="./0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
117
118
const char *prime1080="FBE1022E23D213E8ACFA9AE8B9DFADA3EA6B7AC7A7B7E95AB5EB2DF858921FEADE95E6AC7BE7DE6ADBAB8A783E7AF7A7FA6A2B7BEB1E72EAE2B72F9FA2BFB2A2EFBEFAC868BADB3E828FA8BADFADA3E4CC1BE7E8AFE85E9698A783EB68FA07A77AB6AD7BEB618ACF9CA2897EB28A6189EFA07AB99A8A7FA9AE299EFA7BA66DEAFEFBEFBF0B7D8B";
119
120
int base64dec(char c)
121
{
122
    int i;
123
124
    for (i = 0; i < 64; i++)
125
        if (B64[i] == c) return i;
126
127
    return 0;
128
}
129
130
char *encrypts(char *key,char *str) {
131
  char *result;
132
  unsigned int length;
133
  unsigned int left,right;
134
  char *s,*d;
135
  unsigned char *p;
136
  BF_KEY bfkey;
137
  int i;
138
139
  if(key==NULL||str==NULL) return NULL;
140
141
  length=strlen(str);
142
  BF_set_key(&bfkey, strlen(key), (const unsigned char *)key);
143
144
  s=(char *)malloc(length+9);
145
146
  strncpy(s,str,length);
147
  memset(s+length,0,9);
148
149
  result=(char *)malloc(((length%8==0) ? length/8*12 : 12+length/8*12)+1);
150
151
  p=(unsigned char *)s;
152
  d=result;
153
154
  while(*p) {
155
    BF_ecb_encrypt((const unsigned char *)p, (unsigned char *)p, &bfkey, BF_ENCRYPT);
156
    left = ((*p++) << 24);
157
    left += ((*p++) << 16);
158
    left += ((*p++) << 8);
159
    left += (*p++);
160
    right = ((*p++) << 24);
161
    right += ((*p++) << 16);
162
    right += ((*p++) << 8);
163
    right += (*p++);
164
    for (i = 0; i < 6; i++) {
165
        *d++=B64[right & 0x3f];
166
        right = (right >> 6);
167
    }
168
169
    for (i = 0; i < 6; i++) {
170
        *d++=B64[left & 0x3f];
171
        left = (left >> 6);
172
    }
173
  }
174
  *d = '\0';
175
176
  memset(s,0,length+9);
177
  free(s);
178
  return result;
179
}
180
181
char *decrypts(char *key, char *str) {
182
  char *result;
183
  unsigned int length;
184
  unsigned int left,right;
185
  int i;
186
  char *d;
187
  unsigned char *c;
188
  BF_KEY bfkey;
189
190
  if(key==NULL||str==NULL) return NULL;
191
192
  length=strlen(str);
193
  BF_set_key(&bfkey,strlen(key),(const unsigned char *)key);
194
195
  result=(char *)malloc((length/12*8)+1);
196
  c=(unsigned char *)result;
197
  d=str;
198
  while(*d) {
199
    right=0;
200
    left=0;
201
    for (i = 0; i < 6; i++) right |= (base64dec(*d++)) << (i * 6);
202
	for (i = 0; i < 6; i++) left |= (base64dec(*d++)) << (i * 6);
203
    right=htonl(right);
204
    left=htonl(left);
205
    memcpy(c,&left,4);
206
    memcpy(c+4,&right,4);
207
    BF_ecb_encrypt(c,c,&bfkey,BF_DECRYPT);
208
    c+=8;
209
  }
210
  *c='\0';
211
  return result;
212
}
213
214
class CKeyExchangeTimer : public CTimer {
215
public:
216
	CKeyExchangeTimer(CModule* pModule)
217
		    : CTimer(pModule, 5, 0, "KeyExchangeTimer", "Key exchange timer removes stale exchanges") {}
218
219
protected:
220
	virtual void RunJob();
221
};
222
223
class CFishMod : public CModule {
224
public:
225
	MODCONSTRUCTOR(CFishMod) {}
226
	virtual ~CFishMod() {
227
	}
228
229
        virtual EModRet OnPrivNotice(CNick& Nick, CString& sMessage) {
230
		CString command = sMessage.Token(0);
231
		CString sOtherPub_Key = sMessage.Token(1);
232
233
		if (command.CaseCmp("DH1080_INIT") == 0 && !sOtherPub_Key.empty()) {
234
		    CString sPriv_Key;
235
		    CString sPub_Key;
236
		    CString sSecretKey;
237
238
		    DH1080_gen(sPriv_Key, sPub_Key);
239
		    if (!DH1080_comp(sPriv_Key, sOtherPub_Key, sSecretKey)) {
240
			PutModule("Error in DH1080 with " + Nick.GetNick() + ": " + sSecretKey);
241
			return CONTINUE;
242
		    }
243
		    PutModule("Received DH1080 public key from " + Nick.GetNick() + ", sending mine...");
244
		    PutIRC("NOTICE " + Nick.GetNick() + " :DH1080_FINISH " + sPub_Key);
245
		    SetNV(Nick.GetNick().AsLower(), sSecretKey);
246
		    PutModule("Key for " + Nick.GetNick() + " successfully set.");
247
		    return HALT;
248
		} else if (command.CaseCmp("DH1080_FINISH") == 0 && !sOtherPub_Key.empty()) {
249
		    CString sPriv_Key;
250
		    CString sSecretKey;
251
252
		    map<CString, pair<time_t, CString> >::iterator it = m_msKeyExchange.find(Nick.GetNick().AsLower());
253
		    if (it == m_msKeyExchange.end()) {
254
			PutModule("Received unexpected DH1080_FINISH from " + Nick.GetNick() + ".");
255
		    } else {
256
			sPriv_Key = it->second.second;
257
			if (DH1080_comp(sPriv_Key, sOtherPub_Key, sSecretKey)) {
258
				SetNV(Nick.GetNick().AsLower(), sSecretKey);
259
				PutModule("Key for " + Nick.GetNick() + " successfully set.");
260
				m_msKeyExchange.erase(Nick.GetNick().AsLower());
261
			}
262
		    }
263
		    return HALT;
264
		} else {
265
			FilterIncoming(Nick.GetNick(), Nick, sMessage);
266
		}
267
268
                return CONTINUE;
269
        }
270
271
	virtual EModRet OnUserMsg(CString& sTarget, CString& sMessage) {
272
		MCString::iterator it = FindNV(sTarget.AsLower());
273
274
		if (it != EndNV()) {
275
			CChan* pChan = m_pNetwork->FindChan(sTarget);
276
			if ((pChan) && (pChan->AutoClearChanBuffer())) {
277
				pChan->AddBuffer(":" + m_pNetwork->GetIRCNick().GetNickMask() + " PRIVMSG " + sTarget + " :" + sMessage);
278
			}
279
			char * cMsg = encrypts((char *)it->second.c_str(), (char *)sMessage.c_str());
280
281
			CString sMsg = "+OK " + CString(cMsg);
282
			PutIRC("PRIVMSG " + sTarget + " :" + sMsg);
283
			m_pNetwork->PutUser(":" + m_pNetwork->GetIRCNick().GetNickMask() + " PRIVMSG " + sTarget + " :" + sMessage, NULL, m_pClient);
284
285
			free(cMsg);
286
			return HALTCORE;
287
		}
288
289
		return CONTINUE;
290
	}
291
292
	virtual EModRet OnUserAction(CString& sTarget, CString& sMessage) {
293
		MCString::iterator it = FindNV(sTarget.AsLower());
294
295
		if (it != EndNV()) {
296
			CChan* pChan = m_pNetwork->FindChan(sTarget);
297
			if ((pChan) && (pChan->AutoClearChanBuffer())) {
298
				pChan->AddBuffer(":" + m_pNetwork->GetIRCNick().GetNickMask() + " PRIVMSG " + sTarget + " :\001ACTION " + sMessage + "\001");
299
			}
300
			char * cMsg = encrypts((char *)it->second.c_str(), (char *)sMessage.c_str());
301
302
			CString sMsg = "+OK " + CString(cMsg);
303
			PutIRC("PRIVMSG " + sTarget + " :\001ACTION " + sMsg + "\001");
304
			m_pNetwork->PutUser(":" + m_pNetwork->GetIRCNick().GetNickMask() + " PRIVMSG " + sTarget + " :\001ACTION " + sMessage + "\001", NULL, m_pClient);
305
306
			free(cMsg);
307
			return HALTCORE;
308
		}
309
310
		return CONTINUE;
311
	}
312
313
	virtual EModRet OnUserNotice(CString& sTarget, CString& sMessage) {
314
		MCString::iterator it = FindNV(sTarget.AsLower());
315
316
		if (it != EndNV()) {
317
			CChan* pChan = m_pNetwork->FindChan(sTarget);
318
			if ((pChan) && (pChan->AutoClearChanBuffer())) {
319
				pChan->AddBuffer(":" + m_pNetwork->GetIRCNick().GetNickMask() + " NOTICE " + sTarget + " :" + sMessage);
320
			}
321
			char * cMsg = encrypts((char *)it->second.c_str(), (char *)sMessage.c_str());
322
323
			CString sMsg = "+OK " + CString(cMsg);
324
			PutIRC("NOTICE " + sTarget + " :" + sMsg);
325
			m_pNetwork->PutUser(":" + m_pNetwork->GetIRCNick().GetNickMask() + " NOTICE " + sTarget + " :" + sMessage, NULL, m_pClient);
326
327
			free(cMsg);
328
			return HALTCORE;
329
		}
330
331
		return CONTINUE;
332
333
	}
334
335
	virtual EModRet OnUserTopic(CString& sChannel, CString& sTopic) {
336
		if (!sTopic.empty()) {
337
			MCString::iterator it = FindNV(sChannel.AsLower());
338
			if (it != EndNV()) {
339
				char * cTopic = encrypts((char *)it->second.c_str(), (char *)sTopic.c_str());
340
				sTopic = "+OK " + CString(cTopic);
341
				free(cTopic);
342
			}
343
		}
344
345
		return CONTINUE;
346
	}
347
348
	virtual EModRet OnPrivMsg(CNick& Nick, CString& sMessage) {
349
		FilterIncoming(Nick.GetNick(), Nick, sMessage);
350
		return CONTINUE;
351
	}
352
353
	virtual EModRet OnChanMsg(CNick& Nick, CChan& Channel, CString& sMessage) {
354
		FilterIncoming(Channel.GetName(), Nick, sMessage);
355
		return CONTINUE;
356
	}
357
358
	virtual EModRet OnPrivAction(CNick& Nick, CString& sMessage) {
359
		FilterIncoming(Nick.GetNick(), Nick, sMessage);
360
		return CONTINUE;
361
	}
362
363
	virtual EModRet OnChanAction(CNick& Nick, CChan& Channel, CString& sMessage) {
364
		FilterIncoming(Channel.GetName(), Nick, sMessage);
365
		return CONTINUE;
366
	}
367-
	
367+
368
	virtual EModRet OnTopic(CNick& Nick, CChan& Channel, CString& sTopic) {
369
		FilterIncoming(Channel.GetName(), Nick, sTopic);
370
		return CONTINUE;
371
	}
372
373
	virtual EModRet OnRaw(CString& sLine) {
374
		if (sLine.WildCmp(":* 332 *") && sLine.Token(1) == "332") {
375
			CChan* pChan = m_pNetwork->FindChan(sLine.Token(3));
376
			if (pChan) {
377
				CNick Nick(sLine.Token(2));
378
				CString sTopic = sLine.Token(4, true);
379
				sTopic.LeftChomp();
380
				FilterIncoming(pChan->GetName(), Nick, sTopic);
381
				sLine = sLine.Token(0) + " " + sLine.Token(1) + " " + sLine.Token(2) + " " + pChan->GetName() + " :" + sTopic;
382
			}
383
		}
384
		return CONTINUE;
385
	}
386
387
	void FilterIncoming(const CString& sTarget, CNick& Nick, CString& sMessage) {
388
		if (sMessage.Left(4) == "+OK " || sMessage.Left(5) == "mcps ") {
389
			MCString::iterator it = FindNV(sTarget.AsLower());
390
391
			if (it != EndNV()) {
392
				if (sMessage.Left(4) == "+OK ") {
393
				    sMessage.LeftChomp(4);
394
				} else if (sMessage.Left(5) == "mcps ") {
395
				    sMessage.LeftChomp(5);
396
				}
397
398
				unsigned int msg_len = strlen(sMessage.c_str());
399
400
				if ((strspn(sMessage.c_str(), (char *)B64) != msg_len) || msg_len < 12) {
401
					return;
402
				}
403
404
				unsigned int mark_broken_block = 0;
405
406
				if (msg_len != (msg_len/12)*12) {
407
					msg_len = msg_len - (msg_len/12)*12;
408
					sMessage.RightChomp(msg_len);
409
					mark_broken_block = 1;
410
				}
411
412
				char *cMsg = decrypts((char *)it->second.c_str(), (char *)sMessage.c_str());
413
				sMessage = CString(cMsg);
414
415
				if (mark_broken_block) {
416
					sMessage += "  \002&\002";
417
				}
418
419
				free(cMsg);
420
			}
421
		}
422
	}
423
424
	virtual void OnModCommand(const CString& sCommand) {
425
		CString sCmd = sCommand.Token(0);
426
427
		if (sCmd.CaseCmp("DELKEY") == 0) {
428
			CString sTarget = sCommand.Token(1);
429
430
			if (!sTarget.empty()) {
431
				if (DelNV(sTarget.AsLower())) {
432
					PutModule("Target [" + sTarget + "] deleted");
433
				} else {
434
					PutModule("Target [" + sTarget + "] not found");
435
				}
436
			} else {
437
				PutModule("Usage DelKey <#chan|Nick>");
438
			}
439
		} else if (sCmd.CaseCmp("SETKEY") == 0) {
440
			CString sTarget = sCommand.Token(1);
441
			CString sKey = sCommand.Token(2, true);
442
443
			if (!sKey.empty()) {
444
				SetNV(sTarget.AsLower(), sKey);
445
				PutModule("Set encryption key for [" + sTarget + "] to [" + sKey + "]");
446
			} else {
447
				PutModule("Usage: SetKey <#chan|Nick> <Key>");
448
			}
449
		} else if (sCmd.CaseCmp("SHOWKEY") == 0) {
450
			CString sTarget = sCommand.Token(1);
451
452
			if (!sTarget.empty()) {
453
				MCString::iterator it = FindNV(sTarget.AsLower());
454
455
				if (it != EndNV()) {
456
					PutModule("Target key is " + it->second);
457
				} else {
458
					PutModule("Target not found.");
459
				}
460
			} else {
461
				PutModule("Usage ShowKey <#chan|Nick>");
462
			}
463
		} else if (sCmd.CaseCmp("LISTKEYS") == 0) {
464
			if (BeginNV() == EndNV()) {
465
				PutModule("You have no encryption keys set.");
466
			} else {
467
				CTable Table;
468
				Table.AddColumn("Target");
469
				Table.AddColumn("Key");
470
471
				for (MCString::iterator it = BeginNV(); it != EndNV(); it++) {
472
					Table.AddRow();
473
					Table.SetCell("Target", it->first);
474
					Table.SetCell("Key", it->second);
475
				}
476
477
				if (Table.size()) {
478
					unsigned int uTableIdx = 0;
479
					CString sLine;
480
481
					while (Table.GetLine(uTableIdx++, sLine)) {
482
						PutModule(sLine);
483
					}
484
				}
485
			}
486
		} else if (sCmd.CaseCmp("KEYX") == 0) {
487
			CString sTarget = sCommand.Token(1);
488
489
			if (sTarget.empty()) {
490
			    PutModule("You did not specify a target for the key exchange.");
491
			} else {
492
			    map<CString, pair<time_t, CString> >::iterator it = m_msKeyExchange.find(sTarget.AsLower());
493
			    if (it != m_msKeyExchange.end()) {
494
				PutModule("Keyexchange with " + sTarget + " already in progress.");
495
			    } else {
496
				CString sPriv_Key;
497
				CString sPub_Key;
498
499
				DH1080_gen(sPriv_Key, sPub_Key);
500
				m_msKeyExchange.insert(make_pair(sTarget.AsLower(), make_pair(time(NULL), sPriv_Key)));
501
				PutIRC("NOTICE " + sTarget + " :DH1080_INIT " + sPub_Key);
502
				PutModule("Sent my DH1080 public key to " + sTarget + ", waiting for reply ...");
503
				if (FindTimer("KeyExchangeTimer") == NULL) {
504
				    AddTimer(new CKeyExchangeTimer(this));
505
				}
506
			    }
507
			}
508
		} else if (sCmd.CaseCmp("HELP") == 0) {
509
			PutModule("Try: SetKey <target> <key>, DelKey <target>, ShowKey <target>, ListKeys, KeyX <target>");
510
		} else {
511
			PutModule("Unknown command, try 'Help'");
512
		}
513
	}
514
515
	void DelStaleKeyExchanges(time_t iTime) {
516-
		for (map<CString, pair<time_t, CString> >::const_iterator it = m_msKeyExchange.begin(); it != m_msKeyExchange.end(); it++) {
516+
		map<CString, pair<time_t, CString> >::iterator it = m_msKeyExchange.begin();
517
		while (it != m_msKeyExchange.end()) {
518
		    if (iTime - 5 >= it->second.first) {
519-
		        m_msKeyExchange.erase(it->first);
519+
520
		        it = m_msKeyExchange.erase(it);
521
		    } else {
522
				++it;
523
			}
524
		}
525
		if (m_msKeyExchange.size() <= 0) {
526
		    RemTimer("KeyExchangeTimer");
527
		}
528
	}
529
530
private:
531
532
	void DH1080_gen(CString& sPriv_Key, CString& sPub_Key) {
533
		sPriv_Key = "";
534
		sPub_Key = "";
535
536
		unsigned char raw_buf[200];
537
		unsigned long len;
538
		unsigned char *a, *b;
539
540
		DH *dh;
541
		BIGNUM *b_prime=NULL;
542
		BIGNUM *b_generator=NULL;
543
544
		initb64();
545
546
		dh=DH_new();
547
548
		if (!BN_hex2bn(&b_prime, prime1080)) {
549
		    return;
550
		}
551
552
		if (!BN_dec2bn(&b_generator, "2")) {
553
		    return;
554
		}
555
556
		dh->p=b_prime;
557
		dh->g=b_generator;
558
559
		if (!DH_generate_key(dh)) {
560
		    return;
561
		}
562
563
		len = BN_num_bytes(dh->priv_key);
564
		a = (unsigned char *)malloc(len);
565
		BN_bn2bin(dh->priv_key,a);
566
567
		memset(raw_buf, 0, 200);
568
		htob64((char *)a, (char *)raw_buf, len);
569
		sPriv_Key = CString((char *)raw_buf);
570
		len=BN_num_bytes(dh->pub_key);
571
		b = (unsigned char *)malloc(len);
572
		BN_bn2bin(dh->pub_key,b);
573
		memset(raw_buf, 0, 200);
574
		htob64((char *)b, (char *)raw_buf, len);
575
		sPub_Key = CString((char *)raw_buf);
576
		DH_free(dh);
577
		free(a);
578
		free(b);
579
	}
580
581
582
	bool DH1080_comp(CString& sPriv_Key, CString& sOtherPub_Key, CString& sSecret_Key) {
583
		int len;
584
		unsigned char SHA256digest[32];
585
		char *key;
586
		BIGNUM *b_prime=NULL;
587
		BIGNUM *b_myPrivkey=NULL;
588
		BIGNUM *b_HisPubkey=NULL;
589
		BIGNUM *b_generator=NULL;
590
		DH *dh;
591
		CString sSHA256digest;
592
		unsigned char raw_buf[200];
593
594
		if (!BN_hex2bn(&b_prime, prime1080)) {
595
		    return false;
596
		}
597
598
		if (!BN_dec2bn(&b_generator, "2")) {
599
		    return false;
600
		}
601
602
		dh=DH_new();
603
		dh->p=b_prime;
604
		dh->g=b_generator;
605
606
		memset(raw_buf, 0, 200);
607
		len = b64toh((char *)sPriv_Key.c_str(), (char *)raw_buf);
608
		b_myPrivkey=BN_bin2bn(raw_buf, len, NULL);
609
		dh->priv_key=b_myPrivkey;
610
611
		memset(raw_buf, 0, 200);
612
		len = b64toh((char *)sOtherPub_Key.c_str(), (char *)raw_buf);
613
614
		b_HisPubkey=BN_bin2bn(raw_buf, len, NULL);
615
616
		key=(char *)malloc(DH_size(dh));
617
		memset(key, 0, DH_size(dh));
618
		len=DH_compute_key((unsigned char *)key, b_HisPubkey, dh);
619
		if (len == -1) {
620
			// Bad pub key
621
			unsigned long err = ERR_get_error();
622
			DEBUG("** DH Error:" << ERR_error_string(err,NULL));
623
			DH_free(dh);
624
			BN_clear_free(b_HisPubkey);
625
			free(key);
626
627
			sSecret_Key = CString(ERR_error_string(err,NULL)).Token(4,true,":");
628
			return false;
629
		}
630
631
		SHA256_CTX c;
632
		SHA256_Init(&c);
633
		memset(SHA256digest, 0, 32);
634
		SHA256_Update(&c, key, len);
635
		SHA256_Final(SHA256digest, &c);
636
		memset(raw_buf, 0, 200);
637
		len = htob64((char *)SHA256digest, (char *)raw_buf, 32);
638
		sSecret_Key = "";
639
		sSecret_Key.append((char *)raw_buf, len);
640
641
		DH_free(dh);
642
		BN_clear_free(b_HisPubkey);
643
		free(key);
644
		return true;
645
	}
646
647
	map<CString, pair<time_t, CString> >	m_msKeyExchange;
648
649
};
650
651
void CKeyExchangeTimer::RunJob() {
652
		CFishMod *p = (CFishMod *)m_pModule;
653
		p->DelStaleKeyExchanges(time(NULL));
654
}
655
656
MODULEDEFS(CFishMod, "FiSH encryption for channel/private messages")