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

« back to all changes in this revision

Viewing changes to src/modules/rijndael/libkvirijndael.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:
3
3
//   File : libkvirijndael.cpp
4
4
//   Creation date : Sat Now 4 2000 15:33:12 CEST by Szymon Stefanek
5
5
//
6
 
//   This file is part of the KVirc irc client distribution
 
6
//   This file is part of the KVIrc irc client distribution
7
7
//   Copyright (C) 2000 Till Bush (buti@geocities.com)
8
 
//   Copyright (C) 2000-2008 Szymon Stefanek (pragma at kvirc dot net)
 
8
//   Copyright (C) 2000-2010 Szymon Stefanek (pragma at kvirc dot net)
9
9
//
10
10
//   This program is FREE software. You can redistribute it and/or
11
11
//   modify it under the terms of the GNU General Public License
24
24
//=============================================================================
25
25
 
26
26
#include "libkvirijndael.h"
27
 
#include "rijndael.h"
 
27
#include "Rijndael.h"
28
28
 
29
 
#include "kvi_module.h"
 
29
#include "KviModule.h"
30
30
#include "kvi_debug.h"
31
 
#include "kvi_locale.h"
32
 
#include "kvi_mirccntrl.h"
33
 
#include "kvi_time.h"
 
31
#include "KviLocale.h"
 
32
#include "KviControlCodes.h"
 
33
#include "KviTimeUtils.h"
 
34
#include "UglyBase64.h"
34
35
 
35
36
//#warning "Other engines: mircStrip koi2win colorizer lamerizer etc.."
36
37
 
62
63
 
63
64
 
64
65
#if defined(COMPILE_CRYPT_SUPPORT) || defined(Q_MOC_RUN)
65
 
        #include "kvi_memmove.h"
66
 
        #include "kvi_malloc.h"
67
 
        #include "kvi_pointerlist.h"
 
66
        #include "KviMemory.h"
 
67
        #include "KviPointerList.h"
 
68
        #include "KviCryptEngineDescription.h"
68
69
 
69
70
        static KviPointerList<KviCryptEngine> * g_pEngineList = 0;
70
71
 
112
113
                                encKeyLen = decKeyLen;
113
114
                        } else {
114
115
                                // both keys missing
115
 
                                setLastError(__tr("Missing both encrypt and decrypt key: at least one is needed"));
 
116
                                setLastError(__tr2qs("Missing both encrypt and decrypt key: at least one is needed"));
116
117
                                return false;
117
118
                        }
118
119
                }
119
120
 
120
121
                int defLen = getKeyLen();
121
122
 
122
 
                char * encryptKey = (char *)kvi_malloc(defLen);
123
 
                char * decryptKey = (char *)kvi_malloc(defLen);
 
123
                char * encryptKey = (char *)KviMemory::allocate(defLen);
 
124
                char * decryptKey = (char *)KviMemory::allocate(defLen);
124
125
 
125
126
                if(encKeyLen > defLen)encKeyLen = defLen;
126
 
                kvi_memmove(encryptKey,encKey,encKeyLen);
127
 
                if(encKeyLen < defLen)kvi_memset(encryptKey + encKeyLen,'0',defLen - encKeyLen);
 
127
                KviMemory::move(encryptKey,encKey,encKeyLen);
 
128
                if(encKeyLen < defLen)KviMemory::set(encryptKey + encKeyLen,'0',defLen - encKeyLen);
128
129
 
129
130
                if(decKeyLen > defLen)decKeyLen = defLen;
130
 
                kvi_memmove(decryptKey,decKey,decKeyLen);
131
 
                if(decKeyLen < defLen)kvi_memset(decryptKey + decKeyLen,'0',defLen - decKeyLen);
 
131
                KviMemory::move(decryptKey,decKey,decKeyLen);
 
132
                if(decKeyLen < defLen)KviMemory::set(decryptKey + decKeyLen,'0',defLen - decKeyLen);
132
133
 
133
134
                m_pEncryptCipher = new Rijndael();
134
135
                int retVal = m_pEncryptCipher->init(Rijndael::CBC,Rijndael::Encrypt,(unsigned char *)encryptKey,getKeyLenId());
135
 
                kvi_free(encryptKey);
 
136
                KviMemory::free(encryptKey);
136
137
                if(retVal != RIJNDAEL_SUCCESS)
137
138
                {
138
 
                        kvi_free(decryptKey);
 
139
                        KviMemory::free(decryptKey);
139
140
                        delete m_pEncryptCipher;
140
141
                        m_pEncryptCipher = 0;
141
142
                        setLastErrorFromRijndaelErrorCode(retVal);
144
145
 
145
146
                m_pDecryptCipher = new Rijndael();
146
147
                retVal = m_pDecryptCipher->init(Rijndael::CBC,Rijndael::Decrypt,(unsigned char *)decryptKey,getKeyLenId());
147
 
                kvi_free(decryptKey);
 
148
                KviMemory::free(decryptKey);
148
149
                if(retVal != RIJNDAEL_SUCCESS)
149
150
                {
150
151
                        delete m_pEncryptCipher;
162
163
        {
163
164
                switch(errCode)
164
165
                {
165
 
                        case RIJNDAEL_SUCCESS: setLastError(__tr("Error 0: Success ?")); break;
166
 
                        case RIJNDAEL_UNSUPPORTED_MODE: setLastError(__tr("Unsupported crypt mode")); break;
167
 
                        case RIJNDAEL_UNSUPPORTED_DIRECTION: setLastError(__tr("Unsupported direction")); break;
168
 
                        case RIJNDAEL_UNSUPPORTED_KEY_LENGTH: setLastError(__tr("Unsupported key length")); break;
169
 
                        case RIJNDAEL_BAD_KEY: setLastError(__tr("Bad key data")); break;
170
 
                        case RIJNDAEL_NOT_INITIALIZED: setLastError(__tr("Engine not initialized")); break;
171
 
                        case RIJNDAEL_BAD_DIRECTION: setLastError(__tr("Invalid direction for this engine")); break;
172
 
                        case RIJNDAEL_CORRUPTED_DATA: setLastError(__tr("Corrupted message data or invalid decrypt key")); break;
173
 
                        default: setLastError(__tr("Unknown error")); break;
 
166
                        case RIJNDAEL_SUCCESS: setLastError(__tr2qs("Error 0: Success ?")); break;
 
167
                        case RIJNDAEL_UNSUPPORTED_MODE: setLastError(__tr2qs("Unsupported crypt mode")); break;
 
168
                        case RIJNDAEL_UNSUPPORTED_DIRECTION: setLastError(__tr2qs("Unsupported direction")); break;
 
169
                        case RIJNDAEL_UNSUPPORTED_KEY_LENGTH: setLastError(__tr2qs("Unsupported key length")); break;
 
170
                        case RIJNDAEL_BAD_KEY: setLastError(__tr2qs("Bad key data")); break;
 
171
                        case RIJNDAEL_NOT_INITIALIZED: setLastError(__tr2qs("Engine not initialized")); break;
 
172
                        case RIJNDAEL_BAD_DIRECTION: setLastError(__tr2qs("Invalid direction for this engine")); break;
 
173
                        case RIJNDAEL_CORRUPTED_DATA: setLastError(__tr2qs("Corrupted message data or invalid decrypt key")); break;
 
174
                        default: setLastError(__tr2qs("Unknown error")); break;
174
175
                }
175
176
        }
176
177
 
177
 
        KviCryptEngine::EncryptResult KviRijndaelEngine::encrypt(const char * plainText,KviStr &outBuffer)
 
178
        KviCryptEngine::EncryptResult KviRijndaelEngine::encrypt(const char * plainText,KviCString &outBuffer)
178
179
        {
179
180
                if(!m_pEncryptCipher)
180
181
                {
181
 
                        setLastError(__tr("Ops...encrypt cipher not initialized"));
 
182
                        setLastError(__tr2qs("Ops...encrypt cipher not initialized"));
182
183
                        return KviCryptEngine::EncryptError;
183
184
                }
184
185
                int len = (int)kvi_strLen(plainText);
185
 
                char * buf = (char *)kvi_malloc(len + 16);
 
186
                char * buf = (char *)KviMemory::allocate(len + 16);
186
187
 
187
188
                int retVal = m_pEncryptCipher->padEncrypt((const unsigned char *)plainText,len,(unsigned char *)buf);
188
189
                if(retVal < 0)
189
190
                {
190
 
                        kvi_free(buf);
 
191
                        KviMemory::free(buf);
191
192
                        setLastErrorFromRijndaelErrorCode(retVal);
192
193
                        return KviCryptEngine::EncryptError;
193
194
                }
194
195
 
195
196
                if(!binaryToAscii(buf,retVal,outBuffer))
196
197
                {
197
 
                        kvi_free(buf);
 
198
                        KviMemory::free(buf);
198
199
                        return KviCryptEngine::EncryptError;
199
200
                }
200
 
                kvi_free(buf);
 
201
                KviMemory::free(buf);
201
202
 
202
203
                if(outBuffer.len() > maxEncryptLen())
203
204
                {
204
205
                        if(maxEncryptLen() > 0)
205
206
                        {
206
 
                                setLastError(__tr("Data buffer too long"));
 
207
                                setLastError(__tr2qs("Data buffer too long"));
207
208
                                return KviCryptEngine::EncryptError;
208
209
                        }
209
210
                }
210
 
                outBuffer.prepend(KVI_TEXT_CRYPTESCAPE);
 
211
                outBuffer.prepend(KviControlCodes::CryptEscape);
211
212
                return KviCryptEngine::Encrypted;
212
213
        }
213
214
 
214
 
        KviCryptEngine::DecryptResult KviRijndaelEngine::decrypt(const char * inBuffer,KviStr &plainText)
 
215
        KviCryptEngine::DecryptResult KviRijndaelEngine::decrypt(const char * inBuffer,KviCString &plainText)
215
216
        {
216
217
                if(!m_pDecryptCipher)
217
218
                {
218
 
                        setLastError(__tr("Ops...decrypt cipher not initialized"));
 
219
                        setLastError(__tr2qs("Ops...decrypt cipher not initialized"));
219
220
                        return KviCryptEngine::DecryptError;
220
221
                }
221
222
 
222
 
                if(*inBuffer != KVI_TEXT_CRYPTESCAPE)
 
223
                if(*inBuffer != KviControlCodes::CryptEscape)
223
224
                {
224
225
                        plainText = inBuffer;
225
226
                        return KviCryptEngine::DecryptOkWasPlainText;
238
239
 
239
240
                if(!asciiToBinary(inBuffer,&len,&binary))return KviCryptEngine::DecryptError;
240
241
 
241
 
                char * buf = (char *)kvi_malloc(len + 1);
 
242
                char * buf = (char *)KviMemory::allocate(len + 1);
242
243
 
243
244
                int retVal = m_pDecryptCipher->padDecrypt((const unsigned char *)binary,len,(unsigned char *)buf);
244
 
                kvi_free(binary);
 
245
                KviMemory::free(binary);
245
246
 
246
247
                if(retVal < 0)
247
248
                {
248
 
                        kvi_free(buf);
 
249
                        KviMemory::free(buf);
249
250
                        setLastErrorFromRijndaelErrorCode(retVal);
250
251
                        return KviCryptEngine::DecryptError;
251
252
                }
254
255
 
255
256
                plainText = buf;
256
257
 
257
 
                kvi_free(buf);
 
258
                KviMemory::free(buf);
258
259
                return KviCryptEngine::DecryptOkWasEncrypted;
259
260
        }
260
261
 
261
 
        bool KviRijndaelHexEngine::binaryToAscii(const char * inBuffer,int len,KviStr &outBuffer)
 
262
        bool KviRijndaelHexEngine::binaryToAscii(const char * inBuffer,int len,KviCString &outBuffer)
262
263
        {
263
264
                outBuffer.bufferToHex(inBuffer,len);
264
265
                return true;
266
267
 
267
268
        bool KviRijndaelHexEngine::asciiToBinary(const char * inBuffer,int * len,char ** outBuffer)
268
269
        {
269
 
                KviStr hex(inBuffer);
 
270
                KviCString hex(inBuffer);
270
271
                char * tmpBuf;
271
272
                *len = hex.hexToBuffer(&tmpBuf,false);
272
273
                if(*len < 0)
273
274
                {
274
 
                        setLastError(__tr("The message is not a hexadecimal string: this is not my stuff"));
 
275
                        setLastError(__tr2qs("The message is not a hexadecimal string: this is not my stuff"));
275
276
                        return false;
276
277
                } else {
277
278
                        if(len > 0)
278
279
                        {
279
 
                                *outBuffer = (char *)kvi_malloc(*len);
280
 
                                kvi_memmove(*outBuffer,tmpBuf,*len);
281
 
                                KviStr::freeBuffer(tmpBuf);
 
280
                                *outBuffer = (char *)KviMemory::allocate(*len);
 
281
                                KviMemory::move(*outBuffer,tmpBuf,*len);
 
282
                                KviCString::freeBuffer(tmpBuf);
282
283
                        }
283
284
                }
284
285
                return true;
285
286
        }
286
287
 
287
 
        bool KviRijndaelBase64Engine::binaryToAscii(const char * inBuffer,int len,KviStr &outBuffer)
 
288
        bool KviRijndaelBase64Engine::binaryToAscii(const char * inBuffer,int len,KviCString &outBuffer)
288
289
        {
289
290
                outBuffer.bufferToBase64(inBuffer,len);
290
291
                return true;
292
293
 
293
294
        bool KviRijndaelBase64Engine::asciiToBinary(const char * inBuffer,int * len,char ** outBuffer)
294
295
        {
295
 
                KviStr base64(inBuffer);
 
296
                KviCString base64(inBuffer);
296
297
                char * tmpBuf;
297
298
                *len = base64.base64ToBuffer(&tmpBuf,false);
298
299
                if(*len < 0)
299
300
                {
300
 
                        setLastError(__tr("The message is not a base64 string: this is not my stuff"));
 
301
                        setLastError(__tr2qs("The message is not a base64 string: this is not my stuff"));
301
302
                        return false;
302
303
                } else {
303
304
                        if(len > 0)
304
305
                        {
305
 
                                *outBuffer = (char *)kvi_malloc(*len);
306
 
                                kvi_memmove(*outBuffer,tmpBuf,*len);
307
 
                                KviStr::freeBuffer(tmpBuf);
 
306
                                *outBuffer = (char *)KviMemory::allocate(*len);
 
307
                                KviMemory::move(*outBuffer,tmpBuf,*len);
 
308
                                KviCString::freeBuffer(tmpBuf);
308
309
                        }
309
310
                }
310
311
                return true;
348
349
 
349
350
        // Mircryption stuff
350
351
 
351
 
        #include "ablowfish.h"
 
352
        #include "BlowFish.h"
352
353
 
353
354
        KviMircryptionEngine::KviMircryptionEngine()
354
355
        : KviCryptEngine()
378
379
                                encKeyLen = decKeyLen;
379
380
                        } else {
380
381
                                // both keys missing
381
 
                                setLastError(__tr("Missing both encrypt and decrypt key: at least one is needed"));
 
382
                                setLastError(__tr2qs("Missing both encrypt and decrypt key: at least one is needed"));
382
383
                                return false;
383
384
                        }
384
385
                }
385
 
                m_szEncryptKey = KviStr(encKey,encKeyLen);
386
 
                m_szDecryptKey = KviStr(decKey,decKeyLen);
 
386
                m_szEncryptKey = KviCString(encKey,encKeyLen);
 
387
                m_szDecryptKey = KviCString(decKey,decKeyLen);
387
388
                if(kvi_strEqualCIN("cbc:",m_szEncryptKey.ptr(),4) && (m_szEncryptKey.len() > 4))
388
389
                        m_szEncryptKey.cutLeft(4);
389
390
                else
395
396
                return true;
396
397
        }
397
398
 
398
 
        KviCryptEngine::EncryptResult KviMircryptionEngine::encrypt(const char * plainText,KviStr &outBuffer)
 
399
        KviCryptEngine::EncryptResult KviMircryptionEngine::encrypt(const char * plainText,KviCString &outBuffer)
399
400
        {
400
 
                KviStr szPlain = plainText;
 
401
                KviCString szPlain = plainText;
401
402
                outBuffer = "";
402
403
                if(m_bEncryptCBC)
403
404
                {
411
412
                {
412
413
                        if(maxEncryptLen() > 0)
413
414
                        {
414
 
                                setLastError(__tr("Data buffer too long"));
 
415
                                setLastError(__tr2qs("Data buffer too long"));
415
416
                                return KviCryptEngine::EncryptError;
416
417
                        }
417
418
                }
421
422
                return KviCryptEngine::Encrypted;
422
423
        }
423
424
 
424
 
        KviCryptEngine::DecryptResult KviMircryptionEngine::decrypt(const char * inBuffer,KviStr &plainText)
 
425
        KviCryptEngine::DecryptResult KviMircryptionEngine::decrypt(const char * inBuffer,KviCString &plainText)
425
426
        {
426
427
                plainText = "";
427
 
                KviStr szIn = inBuffer;
 
428
                KviCString szIn = inBuffer;
428
429
                // various old versions
429
430
                if(kvi_strEqualCSN(inBuffer,"mcps ",5))
430
431
                        szIn.cutLeft(5);
431
432
                else if(kvi_strEqualCSN(inBuffer,"+OK ",4))
432
433
                        szIn.cutLeft(4);
 
434
                else if(kvi_strEqualCSN(inBuffer,"OK ",3)) // some servers strip out the +
 
435
                        szIn.cutLeft(3);
433
436
                else {
434
437
                        plainText = szIn;
435
438
                        return KviCryptEngine::DecryptOkWasPlainText;
457
460
                        idx = szIn.findFirstIdx(MCPS2_ENDTAG);
458
461
                        if(idx != -1)
459
462
                        {
460
 
                                KviStr toDecrypt = szIn.left(idx);
 
463
                                KviCString toDecrypt = szIn.left(idx);
461
464
                                if(!doDecrypt(toDecrypt,plainText))return false;
462
465
                        }
463
466
                        szIn.cutLeft(idx + len2);
465
468
                */
466
469
        }
467
470
 
468
 
        static unsigned char fake_base64[]="./0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
469
 
 
470
 
        unsigned int fake_base64dec(unsigned char c)
471
 
        {
472
 
                static char base64unmap[255];
473
 
                static bool didinit=false;
474
 
                int i;
475
 
 
476
 
                if(!didinit)
477
 
                {
478
 
                        // initialize base64unmap
479
 
                        for (i=0;i<255;++i)base64unmap[i]=0;
480
 
                        for (i=0;i<64;++i)base64unmap[fake_base64[i]]=i;
481
 
                        didinit=true;
482
 
                }
483
 
 
484
 
                return base64unmap[c];
485
 
        }
486
 
 
487
 
        static void byteswap_buffer(unsigned char * p,int len)
488
 
        {
489
 
                while(len > 0)
490
 
                {
491
 
                        unsigned char aux = p[0];
492
 
                        p[0] = p[3];
493
 
                        p[3] = aux;
494
 
                        aux = p[1];
495
 
                        p[1] = p[2];
496
 
                        p[2] = aux;
497
 
                        p += 4;
498
 
                        len -= 4;
499
 
                }
500
 
        }
501
 
 
502
 
        bool KviMircryptionEngine::doEncryptECB(KviStr &plain,KviStr &encoded)
 
471
        bool KviMircryptionEngine::doEncryptECB(KviCString &plain,KviCString &encoded)
503
472
        {
504
473
                // make sure it is a multiple of 8 bytes (eventually pad with zeroes)
505
474
                if(plain.len() % 8)
513
482
 
514
483
                //byteswap_buffer((unsigned char *)plain.ptr(),plain.len());
515
484
 
516
 
                unsigned char * out =(unsigned char *)kvi_malloc(plain.len()); // we use this to avoid endiannes problems
 
485
                unsigned char * out =(unsigned char *)KviMemory::allocate(plain.len()); // we use this to avoid endiannes problems
517
486
 
518
487
                BlowFish bf((unsigned char *)m_szEncryptKey.ptr(),m_szEncryptKey.len());
519
488
                bf.ResetChain();
520
489
                bf.Encrypt((unsigned char *)plain.ptr(),out,plain.len(),BlowFish::ECB);
521
490
 
522
 
                // FIXME: this is probably needed only on LittleEndian machines!
523
 
                byteswap_buffer((unsigned char *)out,plain.len());
524
 
 
525
 
                // da uglybase64 encoding
526
 
                unsigned char * outb = out;
527
 
                unsigned char * oute = out + plain.len();
528
 
 
529
 
                int ll = (plain.len() * 3) / 2;
530
 
                encoded.setLength(ll);
531
 
 
532
 
                unsigned char * p = (unsigned char *)encoded.ptr();
533
 
                while(outb < oute)
534
 
                {
535
 
                        quint32 * dd1 = (quint32 *)outb;
536
 
                        outb += 4;
537
 
                        quint32 * dd2 = (quint32 *)outb;
538
 
                        outb += 4;
539
 
                        *p++ = fake_base64[*dd2 & 0x3f]; *dd2 >>= 6;
540
 
                        *p++ = fake_base64[*dd2 & 0x3f]; *dd2 >>= 6;
541
 
                        *p++ = fake_base64[*dd2 & 0x3f]; *dd2 >>= 6;
542
 
                        *p++ = fake_base64[*dd2 & 0x3f]; *dd2 >>= 6;
543
 
                        *p++ = fake_base64[*dd2 & 0x3f]; *dd2 >>= 6;
544
 
                        *p++ = fake_base64[*dd2 & 0x3f];
545
 
 
546
 
                        *p++ = fake_base64[*dd1 & 0x3f]; *dd1 >>= 6;
547
 
                        *p++ = fake_base64[*dd1 & 0x3f]; *dd1 >>= 6;
548
 
                        *p++ = fake_base64[*dd1 & 0x3f]; *dd1 >>= 6;
549
 
                        *p++ = fake_base64[*dd1 & 0x3f]; *dd1 >>= 6;
550
 
                        *p++ = fake_base64[*dd1 & 0x3f]; *dd1 >>= 6;
551
 
                        *p++ = fake_base64[*dd1 & 0x3f];
552
 
                }
553
 
 
554
 
                kvi_free(out);
 
491
                UglyBase64::encode(out, plain.len(), encoded);
 
492
                KviMemory::free(out);
555
493
                return true;
556
494
        }
557
495
 
558
 
        bool KviMircryptionEngine::doDecryptECB(KviStr &encoded,KviStr &plain)
 
496
        bool KviMircryptionEngine::doDecryptECB(KviCString &encoded,KviCString &plain)
559
497
        {
560
 
                // encoded is in this strange base64...
561
 
                // make sure its length is multiple of 12 (eventually pad with zeroes)
562
 
                if(encoded.len() % 12)
563
 
                {
564
 
                        int oldL = encoded.len();
565
 
                        encoded.setLength(encoded.len() + (12 - (encoded.len() % 12)));
566
 
                        char * padB = encoded.ptr() + oldL;
567
 
                        char * padE = encoded.ptr() + encoded.len();
568
 
                        while(padB < padE)*padB++ = 0;
569
 
                }
570
 
 
571
 
                // a fake base64 decoding algo, use a different character set
572
 
                // and stuff 6 bytes at a time into a 32 bit long...
573
 
                int ll = (encoded.len() * 2) / 3;
574
 
 
575
 
                unsigned char * buf = (unsigned char *)kvi_malloc(ll);
576
 
                unsigned char * p = (unsigned char *)encoded.ptr();
577
 
                unsigned char * e = p + encoded.len();
578
 
                int i;
579
 
                unsigned char * bufp = buf;
580
 
                while(p < e)
581
 
                {
582
 
                        quint32 * dw1 = (quint32 *)bufp;
583
 
                        bufp += 4;
584
 
                        quint32 * dw2 = (quint32 *)bufp;
585
 
                        bufp += 4;
586
 
                        *dw2 = 0;
587
 
                        for(i=0;i < 6;i++)*dw2 |= (fake_base64dec(*p++)) << (i * 6);
588
 
                        *dw1 = 0;
589
 
                        for(i=0;i < 6;i++)*dw1 |= (fake_base64dec(*p++)) << (i * 6);
590
 
                }
591
 
 
592
 
                // FIXME: this is probably needed only on LittleEndian machines!
593
 
                byteswap_buffer((unsigned char *)buf,ll);
594
 
 
595
 
                plain.setLength(ll);
 
498
                unsigned char * buf=0;
 
499
                int len;
 
500
                UglyBase64::decode(encoded, &buf, &len);
 
501
 
 
502
                plain.setLength(len);
596
503
                BlowFish bf((unsigned char *)m_szDecryptKey.ptr(),m_szDecryptKey.len());
597
504
                bf.ResetChain();
598
 
                bf.Decrypt(buf,(unsigned char *)plain.ptr(),ll,BlowFish::ECB);
599
 
 
600
 
                //byteswap_buffer((unsigned char *)plain.ptr(),ll);
601
 
 
602
 
                kvi_free(buf);
 
505
                bf.Decrypt(buf,(unsigned char *)plain.ptr(),len,BlowFish::ECB);
 
506
 
 
507
                KviMemory::free(buf);
603
508
 
604
509
                return true;
605
510
        }
606
511
 
607
 
        bool KviMircryptionEngine::doEncryptCBC(KviStr &plain,KviStr &encoded)
 
512
        bool KviMircryptionEngine::doEncryptCBC(KviCString &plain,KviCString &encoded)
608
513
        {
609
514
                // make sure it is a multiple of 8 bytes (eventually pad with zeroes)
610
515
                if(plain.len() % 8)
617
522
                }
618
523
 
619
524
                int ll = plain.len() + 8;
620
 
                unsigned char * in = (unsigned char *)kvi_malloc(ll);
 
525
                unsigned char * in = (unsigned char *)KviMemory::allocate(ll);
621
526
 
622
527
                // choose an IV
623
528
                static bool bDidInit = false;
632
537
 
633
538
                for(int i=0;i<8;i++)in[i] = (unsigned char)(rand() % 256);
634
539
 
635
 
                kvi_fastmove(in+8,plain.ptr(),plain.len());
 
540
                KviMemory::copy(in+8,plain.ptr(),plain.len());
636
541
 
637
542
                // encrypt
638
 
                unsigned char * out = (unsigned char *)kvi_malloc(ll);
 
543
                unsigned char * out = (unsigned char *)KviMemory::allocate(ll);
639
544
                BlowFish bf((unsigned char *)m_szEncryptKey.ptr(),m_szEncryptKey.len());
640
545
                bf.ResetChain();
641
546
                bf.Encrypt(in,out,ll,BlowFish::CBC);
642
 
                kvi_free(in);
 
547
                KviMemory::free(in);
643
548
 
644
549
                encoded.bufferToBase64((const char *)out,ll);
645
 
                kvi_free(out);
 
550
                KviMemory::free(out);
646
551
 
647
552
                encoded.prepend('*'); // prepend the signature
648
553
 
649
554
                return true;
650
555
        }
651
556
 
652
 
        bool KviMircryptionEngine::doDecryptCBC(KviStr &encoded,KviStr &plain)
 
557
        bool KviMircryptionEngine::doDecryptCBC(KviCString &encoded,KviCString &plain)
653
558
        {
654
559
                if(*(encoded.ptr()) != '*')
655
560
                {
656
 
                        debug("WARNING: Specified a CBC key but the incoming message doesn't seem to be a CBC one");
 
561
                        qDebug("WARNING: Specified a CBC key but the incoming message doesn't seem to be a CBC one");
657
562
                        return doDecryptECB(encoded,plain);
658
563
                }
659
564
                encoded.cutLeft(1);
662
567
                int len = encoded.base64ToBuffer(&tmpBuf,false);
663
568
                if(len < 0)
664
569
                {
665
 
                        setLastError(__tr("The message is not a base64 string: this is not my stuff"));
 
570
                        setLastError(__tr2qs("The message is not a base64 string: this is not my stuff"));
666
571
                        return false;
667
572
                }
668
573
                if((len < 8) || (len % 8))
669
574
                {
670
 
                        setLastError(__tr("The message doesn't seem to be encoded with CBC Mircryption"));
671
 
                        if(len > 0)KviStr::freeBuffer(tmpBuf);
 
575
                        setLastError(__tr2qs("The message doesn't seem to be encoded with CBC Mircryption"));
 
576
                        if(len > 0)KviCString::freeBuffer(tmpBuf);
672
577
                        return false;
673
578
                }
674
579
 
680
585
                // kill the first 8 bytes (random IV)
681
586
                plain.cutLeft(8);
682
587
 
683
 
                KviStr::freeBuffer(tmpBuf);
 
588
                KviCString::freeBuffer(tmpBuf);
684
589
 
685
590
                return true;
686
591
        }
703
608
        g_pEngineList = new KviPointerList<KviCryptEngine>;
704
609
        g_pEngineList->setAutoDelete(false);
705
610
 
706
 
        KviStr format = __tr("Cryptographic engine based on the\n" \
 
611
        QString szFormat = __tr2qs("Cryptographic engine based on the\n" \
707
612
                "Advanced Encryption Standard (AES)\n" \
708
613
                "algorithm called Rijndael.\n" \
709
614
                "The text is first encrypted with rijndael\n" \
710
 
                "and then converted to %s notation.\n" \
711
 
                "The keys used are %d bit long and will be padded\n" \
 
615
                "and then converted to %1 notation.\n" \
 
616
                "The keys used are %2 bit long and will be padded\n" \
712
617
                "with zeros if you provide shorter ones.\n" \
713
618
                "If only one key is provided, this engine\n" \
714
619
                "will use it for both encrypting and decrypting.\n" \
718
623
        // FIXME: Maybe convert this repeated code to a function eh ?
719
624
 
720
625
        KviCryptEngineDescription * d = new KviCryptEngineDescription;
721
 
        d->szName = "Rijndael128Hex";
722
 
        d->szAuthor = "Szymon Stefanek";
723
 
        d->szDescription.sprintf(format.ptr(),__tr("hexadecimal"),128);
724
 
        d->iFlags = KVI_CRYPTENGINE_CAN_ENCRYPT | KVI_CRYPTENGINE_CAN_DECRYPT |
725
 
                        KVI_CRYPTENGINE_WANT_ENCRYPT_KEY | KVI_CRYPTENGINE_WANT_DECRYPT_KEY;
726
 
        d->allocFunc = allocRijndael128HexEngine;
727
 
        d->deallocFunc = deallocRijndaelCryptEngine;
728
 
        m->registerCryptEngine(d);
729
 
 
730
 
        d = new KviCryptEngineDescription;
731
 
        d->szName = "Rijndael192Hex";
732
 
        d->szAuthor = "Szymon Stefanek";
733
 
        d->szDescription.sprintf(format.ptr(),__tr("hexadecimal"),192);
734
 
        d->iFlags = KVI_CRYPTENGINE_CAN_ENCRYPT | KVI_CRYPTENGINE_CAN_DECRYPT |
735
 
                        KVI_CRYPTENGINE_WANT_ENCRYPT_KEY | KVI_CRYPTENGINE_WANT_DECRYPT_KEY;
736
 
        d->allocFunc = allocRijndael192HexEngine;
737
 
        d->deallocFunc = deallocRijndaelCryptEngine;
738
 
        m->registerCryptEngine(d);
739
 
 
740
 
        d = new KviCryptEngineDescription;
741
 
        d->szName = "Rijndael256Hex";
742
 
        d->szAuthor = "Szymon Stefanek";
743
 
        d->szDescription.sprintf(format.ptr(),__tr("hexadecimal"),256);
744
 
        d->iFlags = KVI_CRYPTENGINE_CAN_ENCRYPT | KVI_CRYPTENGINE_CAN_DECRYPT |
745
 
                        KVI_CRYPTENGINE_WANT_ENCRYPT_KEY | KVI_CRYPTENGINE_WANT_DECRYPT_KEY;
746
 
        d->allocFunc = allocRijndael256HexEngine;
747
 
        d->deallocFunc = deallocRijndaelCryptEngine;
748
 
        m->registerCryptEngine(d);
749
 
 
750
 
        d = new KviCryptEngineDescription;
751
 
        d->szName = "Rijndael128Base64";
752
 
        d->szAuthor = "Szymon Stefanek";
753
 
        d->szDescription.sprintf(format.ptr(),__tr("base64"),128);
754
 
        d->iFlags = KVI_CRYPTENGINE_CAN_ENCRYPT | KVI_CRYPTENGINE_CAN_DECRYPT |
755
 
                        KVI_CRYPTENGINE_WANT_ENCRYPT_KEY | KVI_CRYPTENGINE_WANT_DECRYPT_KEY;
756
 
        d->allocFunc = allocRijndael128Base64Engine;
757
 
        d->deallocFunc = deallocRijndaelCryptEngine;
758
 
        m->registerCryptEngine(d);
759
 
 
760
 
        d = new KviCryptEngineDescription;
761
 
        d->szName = "Rijndael192Base64";
762
 
        d->szAuthor = "Szymon Stefanek";
763
 
        d->szDescription.sprintf(format.ptr(),__tr("base64"),192);
764
 
        d->iFlags = KVI_CRYPTENGINE_CAN_ENCRYPT | KVI_CRYPTENGINE_CAN_DECRYPT |
765
 
                        KVI_CRYPTENGINE_WANT_ENCRYPT_KEY | KVI_CRYPTENGINE_WANT_DECRYPT_KEY;
766
 
        d->allocFunc = allocRijndael192Base64Engine;
767
 
        d->deallocFunc = deallocRijndaelCryptEngine;
768
 
        m->registerCryptEngine(d);
769
 
 
770
 
        d = new KviCryptEngineDescription;
771
 
        d->szName = "Rijndael256Base64";
772
 
        d->szAuthor = "Szymon Stefanek";
773
 
        d->szDescription.sprintf(format.ptr(),__tr("base64"),256);
774
 
        d->iFlags = KVI_CRYPTENGINE_CAN_ENCRYPT | KVI_CRYPTENGINE_CAN_DECRYPT |
775
 
                        KVI_CRYPTENGINE_WANT_ENCRYPT_KEY | KVI_CRYPTENGINE_WANT_DECRYPT_KEY;
776
 
        d->allocFunc = allocRijndael256Base64Engine;
777
 
        d->deallocFunc = deallocRijndaelCryptEngine;
778
 
        m->registerCryptEngine(d);
779
 
 
780
 
 
781
 
        d = new KviCryptEngineDescription;
782
 
        d->szName = "Mircryption";
783
 
        d->szAuthor = "Szymon Stefanek";
784
 
        d->szDescription = __tr("Popular cryptographic engine based on the\n" \
 
626
        d->m_szName = "Rijndael128Hex";
 
627
        d->m_szAuthor = "Szymon Stefanek";
 
628
        d->m_szDescription = QString(szFormat).arg(__tr2qs("hexadecimal")).arg(128);
 
629
        d->m_iFlags = KviCryptEngine::CanEncrypt | KviCryptEngine::CanDecrypt |
 
630
                KviCryptEngine::WantEncryptKey | KviCryptEngine::WantDecryptKey;
 
631
        d->m_allocFunc = allocRijndael128HexEngine;
 
632
        d->m_deallocFunc = deallocRijndaelCryptEngine;
 
633
        m->registerCryptEngine(d);
 
634
 
 
635
        d = new KviCryptEngineDescription;
 
636
        d->m_szName = "Rijndael192Hex";
 
637
        d->m_szAuthor = "Szymon Stefanek";
 
638
        d->m_szDescription = QString(szFormat).arg(__tr2qs("hexadecimal")).arg(192);
 
639
        d->m_iFlags = KviCryptEngine::CanEncrypt | KviCryptEngine::CanDecrypt |
 
640
                KviCryptEngine::WantEncryptKey | KviCryptEngine::WantDecryptKey;
 
641
        d->m_allocFunc = allocRijndael192HexEngine;
 
642
        d->m_deallocFunc = deallocRijndaelCryptEngine;
 
643
        m->registerCryptEngine(d);
 
644
 
 
645
        d = new KviCryptEngineDescription;
 
646
        d->m_szName = "Rijndael256Hex";
 
647
        d->m_szAuthor = "Szymon Stefanek";
 
648
        d->m_szDescription = QString(szFormat).arg(__tr2qs("hexadecimal")).arg(256);
 
649
        d->m_iFlags = KviCryptEngine::CanEncrypt | KviCryptEngine::CanDecrypt |
 
650
                KviCryptEngine::WantEncryptKey | KviCryptEngine::WantDecryptKey;
 
651
        d->m_allocFunc = allocRijndael256HexEngine;
 
652
        d->m_deallocFunc = deallocRijndaelCryptEngine;
 
653
        m->registerCryptEngine(d);
 
654
 
 
655
        d = new KviCryptEngineDescription;
 
656
        d->m_szName = "Rijndael128Base64";
 
657
        d->m_szAuthor = "Szymon Stefanek";
 
658
        d->m_szDescription = QString(szFormat).arg(__tr2qs("base64")).arg(128);
 
659
        d->m_iFlags = KviCryptEngine::CanEncrypt | KviCryptEngine::CanDecrypt |
 
660
                KviCryptEngine::WantEncryptKey | KviCryptEngine::WantDecryptKey;
 
661
        d->m_allocFunc = allocRijndael128Base64Engine;
 
662
        d->m_deallocFunc = deallocRijndaelCryptEngine;
 
663
        m->registerCryptEngine(d);
 
664
 
 
665
        d = new KviCryptEngineDescription;
 
666
        d->m_szName = "Rijndael192Base64";
 
667
        d->m_szAuthor = "Szymon Stefanek";
 
668
        d->m_szDescription = QString(szFormat).arg(__tr2qs("base64")).arg(192);
 
669
        d->m_iFlags = KviCryptEngine::CanEncrypt | KviCryptEngine::CanDecrypt |
 
670
                KviCryptEngine::WantEncryptKey | KviCryptEngine::WantDecryptKey;
 
671
        d->m_allocFunc = allocRijndael192Base64Engine;
 
672
        d->m_deallocFunc = deallocRijndaelCryptEngine;
 
673
        m->registerCryptEngine(d);
 
674
 
 
675
        d = new KviCryptEngineDescription;
 
676
        d->m_szName = "Rijndael256Base64";
 
677
        d->m_szAuthor = "Szymon Stefanek";
 
678
        d->m_szDescription = QString(szFormat).arg(__tr2qs("base64")).arg(256);
 
679
        d->m_iFlags = KviCryptEngine::CanEncrypt | KviCryptEngine::CanDecrypt |
 
680
                KviCryptEngine::WantEncryptKey | KviCryptEngine::WantDecryptKey;
 
681
        d->m_allocFunc = allocRijndael256Base64Engine;
 
682
        d->m_deallocFunc = deallocRijndaelCryptEngine;
 
683
        m->registerCryptEngine(d);
 
684
 
 
685
 
 
686
        d = new KviCryptEngineDescription;
 
687
        d->m_szName = "Mircryption";
 
688
        d->m_szAuthor = "Szymon Stefanek";
 
689
        d->m_szDescription = __tr2qs("Popular cryptographic engine based on the\n" \
785
690
                "old Blowfish encryption algorithm.\n" \
786
691
                "The text is first encrypted with Blowfish \n" \
787
692
                "and then converted to base64 notation.\n" \
793
698
                "This engine works in ECB mode by default:\n" \
794
699
                "if you want to use CBC mode you must prefix\n" \
795
700
                "your key(s) with \"cbc:\".\n");
796
 
        d->iFlags = KVI_CRYPTENGINE_CAN_ENCRYPT | KVI_CRYPTENGINE_CAN_DECRYPT |
797
 
                        KVI_CRYPTENGINE_WANT_ENCRYPT_KEY | KVI_CRYPTENGINE_WANT_DECRYPT_KEY;
798
 
        d->allocFunc = allocMircryptionEngine;
799
 
        d->deallocFunc = deallocRijndaelCryptEngine;
 
701
        d->m_iFlags = KviCryptEngine::CanEncrypt | KviCryptEngine::CanDecrypt |
 
702
                KviCryptEngine::WantEncryptKey | KviCryptEngine::WantDecryptKey;
 
703
        d->m_allocFunc = allocMircryptionEngine;
 
704
        d->m_deallocFunc = deallocRijndaelCryptEngine;
800
705
        m->registerCryptEngine(d);
801
706
 
802
707
 
809
714
static bool rijndael_module_cleanup(KviModule *m)
810
715
{
811
716
#ifdef COMPILE_CRYPT_SUPPORT
812
 
        while(g_pEngineList->first())delete g_pEngineList->first();
 
717
        while(g_pEngineList->first())
 
718
                delete g_pEngineList->first();
813
719
        delete g_pEngineList;
814
720
        g_pEngineList = 0;
815
721
        m->unregisterCryptEngines();
834
740
KVIRC_MODULE(
835
741
        "Rijndael crypt engine",
836
742
        "4.0.0",
837
 
        "Szymon Stefanek <pragma at kvirc dot net>" ,
 
743
        "Szymon Stefanek <pragma at kvirc dot net>",
838
744
        "Exports the rijndael crypt engine",
839
 
        rijndael_module_init ,
 
745
        rijndael_module_init,
840
746
        rijndael_module_can_unload,
841
747
        0,
842
748
        rijndael_module_cleanup,