source: nscp/modules/NSCAAgent/nsca_enrypt.hpp @ f3da50a

stable
Last change on this file since f3da50a was 358cda1, checked in by Michael Medin <michael@…>, 4 years ago

2009-08-30 MickeM

+ Added -c and -d command line options like so:

NSClient++ -c CheckFile2 path=c:\test pattern=*.txt MaxCrit=1 filter+written=gt:2h
NSClient++ -c <command> <argument 1> <argument 2> ...
-d Is the same thing but with debug enabled.

+ Added uninstall of old client (sort of broken but works)

2009-08-29 MickeM

  • Fixed issue with CheckFile (directory)
  • Rewrote the CA:s in the installer to work "better" (hopefully) in general it should be have more like a propper installer.

2009-07-18 MickeM

  • Fixed issue with no loggers avalible and "memory leak"
  • Added "firewall exception" to installer
  • Fixed an issue with the socket data buffer
  • Added new option to NSC.ini [NSCA] socket_timeout=30 (timeout in seconds when reading from NSCA sockets)
  • Fixed issue with NSCA socket.

2009-07-05 MickeM

2009-06-20 MickeM

  • Fixed issue with CheckDisk and paths not working out properly
  • Property mode set to 100644
File size: 11.2 KB
Line 
1#ifdef HAVE_LIBCRYPTOPP
2#include <cryptopp/cryptlib.h>
3#include <cryptopp/modes.h>
4#include <cryptopp/des.h>
5#include <cryptopp/aes.h>
6#include <cryptopp/cast.h>
7#include <cryptopp/tea.h>
8#include <cryptopp/3way.h>
9#include <cryptopp/blowfish.h>
10#include <cryptopp/twofish.h>
11#include <cryptopp/rc2.h>
12#include <cryptopp/arc4.h>
13#include <cryptopp/serpent.h>
14#include <cryptopp/gost.h>
15#include <cryptopp/filters.h>
16#include <cryptopp/osrng.h>
17#endif
18
19#define TRANSMITTED_IV_SIZE     128     /* size of IV to transmit - must be as big as largest IV needed for any crypto algorithm */
20
21/********************* ENCRYPTION TYPES ****************/
22
23#define ENCRYPT_NONE            0       /* no encryption */
24#define ENCRYPT_XOR             1       /* not really encrypted, just obfuscated */
25
26#ifdef HAVE_LIBCRYPTOPP
27#define ENCRYPT_DES             2       /* DES */
28#define ENCRYPT_3DES            3       /* 3DES or Triple DES */
29#define ENCRYPT_CAST128         4       /* CAST-128 */
30#define ENCRYPT_CAST256         5       /* CAST-256 */
31#define ENCRYPT_XTEA            6       /* xTEA */
32#define ENCRYPT_3WAY            7       /* 3-WAY */
33#define ENCRYPT_BLOWFISH        8       /* SKIPJACK */
34#define ENCRYPT_TWOFISH         9       /* TWOFISH */
35#define ENCRYPT_LOKI97          10      /* LOKI97 */
36#define ENCRYPT_RC2             11      /* RC2 */
37#define ENCRYPT_ARCFOUR         12      /* RC4 */
38#define ENCRYPT_RC6             13      /* RC6 */            /* UNUSED */
39#define ENCRYPT_RIJNDAEL128     14      /* RIJNDAEL-128 */
40#define ENCRYPT_RIJNDAEL192     15      /* RIJNDAEL-192 */
41#define ENCRYPT_RIJNDAEL256     16      /* RIJNDAEL-256 */
42#define ENCRYPT_MARS            17      /* MARS */           /* UNUSED */
43#define ENCRYPT_PANAMA          18      /* PANAMA */         /* UNUSED */
44#define ENCRYPT_WAKE            19      /* WAKE */
45#define ENCRYPT_SERPENT         20      /* SERPENT */
46#define ENCRYPT_IDEA            21      /* IDEA */           /* UNUSED */
47#define ENCRYPT_ENIGMA          22      /* ENIGMA (Unix crypt) */
48#define ENCRYPT_GOST            23      /* GOST */
49#define ENCRYPT_SAFER64         24      /* SAFER-sk64 */
50#define ENCRYPT_SAFER128        25      /* SAFER-sk128 */
51#define ENCRYPT_SAFERPLUS       26      /* SAFER+ */
52#endif
53#define LAST_ENCRYPTION_ID 26
54
55class nsca_encrypt {
56public:
57        class encryption_exception {
58                std::wstring msg_;
59        public:
60                encryption_exception() {}
61                encryption_exception(std::wstring msg) : msg_(msg) {}
62                std::wstring getMessage() const { return msg_; }
63
64        };
65        class any_encryption {
66        public:
67                virtual void init(std::string password, unsigned char *transmitted_iv, int iv_size) = 0;
68                virtual void encrypt(unsigned char *buffer, int buffer_size) = 0;
69                virtual void decrypt(unsigned char *buffer, int buffer_size) = 0;
70                virtual std::wstring getName() = 0;
71        };
72#ifdef HAVE_LIBCRYPTOPP
73        template <class TMethod>
74        class cryptopp_encryption : public any_encryption {
75        private:
76                typedef CryptoPP::CFB_Mode_ExternalCipher::Encryption TEncryption;
77                typedef typename TMethod::Encryption TCipher;
78                TEncryption crypto_;
79                TCipher cipher_;
80                int keysize_;
81        public:
82                cryptopp_encryption() : keysize_(TMethod::DEFAULT_KEYLENGTH) {}
83                cryptopp_encryption(int keysize) : keysize_(keysize) {}
84                int get_keySize() {
85                        return keysize_;
86                }
87                int get_blockSize() {
88                        return TMethod::BLOCKSIZE;
89                }
90
91                void init(std::string password, unsigned char *transmitted_iv, int iv_size) {
92                        /* generate an encryption/description key using the password */
93                        unsigned int keysize=get_keySize();
94
95                        unsigned char *key = new unsigned char[keysize+1];
96                        if (key == NULL){
97                                throw encryption_exception(_T("Could not allocate memory for encryption/decryption key"));
98                        }
99                        ZeroMemory(key,keysize*sizeof(unsigned char));
100                        strncpy(reinterpret_cast<char*>(key),password.c_str(),min(keysize,password.length()));
101
102
103                        /* determine size of IV buffer for this algorithm */
104                        int blocksize = get_blockSize();
105                        if(blocksize>iv_size){
106                                throw encryption_exception(_T("IV size for crypto algorithm exceeds limits"));
107                        }
108
109                        /* allocate memory for IV buffer */
110                        unsigned char *iv = new unsigned char[blocksize+1];
111                        if (iv == NULL){
112                                throw encryption_exception(_T("Could not allocate memory for IV buffer"));
113                        }
114
115                        /* fill IV buffer with first bytes of IV that is going to be used to crypt (determined by server) */
116                        memcpy(iv, transmitted_iv, sizeof(unsigned char)*blocksize);
117
118                        try {
119                                cipher_.SetKey(key, keysize);
120                                crypto_.SetCipherWithIV(cipher_, iv, 1);
121                        } catch (...) {
122                                throw encryption_exception(_T("Unknown exception when trying to setup crypto"));
123                        }
124                        delete [] iv;
125                        delete [] key;
126                }
127                void encrypt(unsigned char *buffer, int buffer_size) {
128                        /* encrypt each byte of buffer, one byte at a time (CFB mode) */
129                        try {
130                                for(int x=0;x<buffer_size;x++)
131                                        crypto_.ProcessData(&buffer[x], &buffer[x], 1);
132                        } catch (...) {
133                                throw encryption_exception(_T("Unknown exception when trying to setup crypto"));
134                        }
135                }
136                void decrypt(unsigned char *buffer, int buffer_size) {
137                        throw encryption_exception(_T("Decryption not supported"));
138                }
139                std::wstring getName() {
140                        return strEx::string_to_wstring(TMethod::StaticAlgorithmName());
141                }
142
143        };
144#endif
145        class no_encryption : public any_encryption {
146        public:
147                static int get_keySize() {
148                        return 0;
149                }
150                static int get_blockSize() {
151                        return 1;
152                }
153                void init(std::string password, unsigned char *transmitted_iv, int iv_size) {}
154                void encrypt(unsigned char *buffer, int buffer_size) {}
155                void decrypt(unsigned char *buffer, int buffer_size) {}
156                std::wstring getName() {
157                        return _T("No Encryption (not safe)");
158                }
159        };
160        class xor_encryption : public any_encryption {
161        private:
162                int password_size_;
163                int iv_size_;
164                unsigned char* transmitted_iv_;
165                unsigned char* password_;
166        public:
167                xor_encryption() : transmitted_iv_(NULL), password_(NULL) {}
168                ~xor_encryption() {
169                        delete [] password_;
170                        delete [] transmitted_iv_;
171                }
172                static int get_keySize() {
173                        return 0;
174                }
175                static int get_blockSize() {
176                        return 1;
177                }
178                void init(std::string password, unsigned char *transmitted_iv, int iv_size) {
179                        iv_size_ = iv_size;
180                        delete [] transmitted_iv_;
181                        transmitted_iv_ = new unsigned char[iv_size_+1];
182                        if (transmitted_iv_ == NULL)
183                                throw encryption_exception(_T("Failed to allocate memory for iv"));
184                        memcpy(transmitted_iv_, transmitted_iv, sizeof(unsigned char)*iv_size_);
185
186                        password_size_ = password.length();
187                        delete [] password_;
188                        password_ = new unsigned char[password_size_+1];
189                        if (password_ == NULL)
190                                throw encryption_exception(_T("Failed to allocate memory for password"));
191                        memcpy(password_, password.c_str(), sizeof(unsigned char)*password_size_);
192
193                }
194                void encrypt(unsigned char *buffer, int buffer_size) {
195                        /* rotate over IV we received from the server... */
196                        for (int y=0,x=0;y<buffer_size;y++,x++) {
197                                /* keep rotating over IV */
198                                if (x >= iv_size_)
199                                        x = 0;
200                                buffer[y] ^= transmitted_iv_[x];
201                        }
202
203                        /* rotate over password... */
204                        for(int y=0,x=0; y < buffer_size; y++,x++) {
205                                /* keep rotating over password */
206                                if (x >= password_size_)
207                                        x = 0;
208                                buffer[y] ^= password_[x];
209                        }
210                        return;
211                }
212                void decrypt(unsigned char *buffer, int buffer_size) {
213                        throw encryption_exception(_T("Decryption not supported"));
214                }
215                std::wstring getName() {
216                        return _T("XOR (not safe)");
217                }
218        };
219
220private:
221        any_encryption *core_;
222public:
223
224        nsca_encrypt() : core_(NULL) {}
225        ~nsca_encrypt() {
226                delete core_;
227        }
228
229
230        static bool hasEncryption(int encryption_method) {
231                switch(encryption_method) {
232                        case ENCRYPT_NONE:
233                        case ENCRYPT_XOR:
234#ifdef HAVE_LIBCRYPTOPP
235                        case ENCRYPT_DES:
236                        case ENCRYPT_3DES:
237                        case ENCRYPT_CAST128:
238                        case ENCRYPT_XTEA:
239                        case ENCRYPT_BLOWFISH:
240                        case ENCRYPT_TWOFISH:
241                        case ENCRYPT_RC2:
242                        case ENCRYPT_RIJNDAEL128:
243                        case ENCRYPT_SERPENT:
244                        case ENCRYPT_GOST:
245#endif
246                                return true;
247
248// UNdefined
249#ifdef HAVE_LIBCRYPTOPP
250                        case ENCRYPT_3WAY:
251                        case ENCRYPT_ARCFOUR:
252                        case ENCRYPT_CAST256:
253                        case ENCRYPT_LOKI97:
254                        case ENCRYPT_WAKE:
255                        case ENCRYPT_ENIGMA:
256                        case ENCRYPT_RIJNDAEL192:
257                        case ENCRYPT_RIJNDAEL256:
258                        case ENCRYPT_SAFER64:
259                        case ENCRYPT_SAFER128:
260                        case ENCRYPT_SAFERPLUS:
261#endif
262                        default:
263                                return false;
264                }
265        }
266
267
268        static any_encryption* get_encryption_core(int encryption_method) {
269                switch(encryption_method) {
270        case ENCRYPT_NONE:
271                return new no_encryption();
272        case ENCRYPT_XOR:
273                return new xor_encryption();
274#ifdef HAVE_LIBCRYPTOPP
275        case ENCRYPT_DES:
276                return new cryptopp_encryption<CryptoPP::DES>();
277        case ENCRYPT_3DES:
278                return new cryptopp_encryption<CryptoPP::DES_EDE3>();
279        case ENCRYPT_CAST128:
280                return new cryptopp_encryption<CryptoPP::CAST128>();
281        case ENCRYPT_XTEA:
282                return new cryptopp_encryption<CryptoPP::XTEA>();
283        case ENCRYPT_3WAY:
284                return new cryptopp_encryption<CryptoPP::ThreeWay>();
285        case ENCRYPT_BLOWFISH:
286                return new cryptopp_encryption<CryptoPP::Blowfish>(56);
287        case ENCRYPT_TWOFISH:
288                return new cryptopp_encryption<CryptoPP::Twofish>(32);
289        case ENCRYPT_RC2:
290                return new cryptopp_encryption<CryptoPP::RC2>(128);
291        case ENCRYPT_RIJNDAEL128:
292                return new cryptopp_encryption<CryptoPP::AES>(32);
293        case ENCRYPT_SERPENT:
294                return new cryptopp_encryption<CryptoPP::Serpent>(32);
295        case ENCRYPT_GOST:
296                return new cryptopp_encryption<CryptoPP::GOST>();
297#endif
298        default:
299                return NULL;
300                }
301        }
302        static void generate_transmitted_iv(unsigned char *transmitted_iv){
303                int x;
304                int seed=0;
305
306                /*********************************************************/
307                /* fill IV buffer with data that's as random as possible */
308                /*********************************************************/
309
310                /* else fall back to using the current time as the seed */
311                seed=(int)time(NULL);
312
313                /* generate pseudo-random IV */
314                srand(seed);
315                for(x=0;x<TRANSMITTED_IV_SIZE;x++)
316                        transmitted_iv[x]=(int)((256.0*rand())/(RAND_MAX+1.0));
317
318                return;
319        }
320
321        /* initializes encryption routines */
322        void encrypt_init(std::string password, int encryption_method, unsigned char *received_iv){
323                delete core_;
324                core_ = get_encryption_core(encryption_method);
325                if (core_ == NULL)
326                        throw encryption_exception(_T("Failed to get encryption core!"));
327
328                /* server generates IV used for encryption */
329                if (received_iv==NULL) {
330                        unsigned char generated_iv[TRANSMITTED_IV_SIZE];
331                        generate_transmitted_iv(generated_iv);
332                        core_->init(password, generated_iv, TRANSMITTED_IV_SIZE);
333                } else  /* client receives IV from server */
334                        core_->init(password, received_iv, TRANSMITTED_IV_SIZE);
335        }
336
337        /* encrypt a buffer */
338        void encrypt_buffer(unsigned char *buffer,int buffer_size) {
339                if (core_ == NULL)
340                        throw encryption_exception(_T("No encryption core!"));
341                core_->encrypt(buffer, buffer_size);
342        }
343        unsigned char* get_rand_buffer(int length) {
344                unsigned char * buffer = new unsigned char[length+1];
345#if HAVE_LIBCRYPTOPP
346                CryptoPP::AutoSeededRandomPool rng;
347                rng.GenerateBlock(buffer, length);
348#endif
349                return buffer;
350        }
351        void destroy_random_buffer(unsigned char* buffer) {
352                delete [] buffer;
353        }
354
355};
Note: See TracBrowser for help on using the repository browser.