Fixed several compiler warnings
[lcr.git] / crypt.cpp
1 /*****************************************************************************\
2 **                                                                           **
3 ** PBX4Linux                                                                 **
4 **                                                                           **
5 **---------------------------------------------------------------------------**
6 ** Copyright: Andreas Eversberg                                              **
7 **                                                                           **
8 ** cryption stuff                                                            **
9 **                                                                           **
10 \*****************************************************************************/ 
11
12 /* how authentication is performed:
13
14 Alice                                                         Bob
15 -----------------------------------------------------------------
16                          unencrypted call
17 start        *
18              | -----> sending random number -----> (gets lost)
19              |
20              |                                     *        start
21 comparing    | <----- sending random number <----- |
22 master state |                                     |
23              | -----> sending "slave" code  -----> |  slave state
24 calculating  |                                     |
25 rsa key pair |                                     |
26              |                                     |
27 done         | -----> sending public key    -----> |
28              |                                     |     crpyting
29              |                                     |  session key
30              |                                     |
31              | <----- sending session key   <----- |         done
32 decrypting   |                                     | enable crypt
33 dession key  |                                     *         stop
34              |
35 done         |
36 enable crypt |
37 stop         *
38                          encrypted call
39
40 When Bob and Alice activate their authentication process, they will make
41 up a random number.
42
43 Lets assume Alice starts encryption first. She activates the authentication
44 process. Bob hat not activates the process yet. Alice sends a random number
45 to Bob, but he will ignore it, because he is not listening.
46
47 Bob also activates the authentication process, and sends his random number.
48 Now Alice will receive that number and compares the values. If the values
49 are equal, the process will fail and Alice will send the message "LOOPED".
50 If Alice's random number is greater, she will identify herself as "master".
51 Bob will get a "SLAVE" message. Bob might also send a "MASTER" message,
52 if he got Alice's random number, due to parallel activation of the
53 authentication.
54
55 After transmission or reception of a master message, more messages are
56 ignored. After reception of a "RANDOM" message, more messages are
57 ignored. A reception of a "RANDOM" message always causes to identify who
58 is slave.
59
60 Now Alice starts calculating his public/private key pair, because she is
61 "master". When Bob receives the "SLAVE" message, he will change the timeout
62 value. If no random number or "SLAVE", "MASTER" or "LOOPED" is received within
63 a timeout value, the "ABORT" message is sent. If the "ABORT" message is
64 received at any state of the process, the process is aborted.
65
66 After the key of Alices is calculated, she will send it to Bob. Bob will use
67 the key to start encryption of a random session key. Both will change their
68 timeout values.
69
70 After Bob has finished is crypted session key, he will send it to Alice and
71 enable encryption. Bob has finished his process now.
72
73 As soon as Alice received the encrypted key, she will encrypt it and also
74 enable encryption with the same key as Bob. Alis has finished her process now.
75
76 Both will get displayed some of the first digits of the public key. Both can
77 talk about the digits now. A man in the middle cannot change the keys without
78 changing the public key. The voice of Alice and/or Bob is used to "sign" and
79 "check" that the public key is not modified.
80
81 If Alice or Bob wants to stop encryption, one will send the "ABORT" message.
82 After transmission or reception.
83
84
85 The states of the process:
86
87 CM_ST_NULL
88 ----------
89 no encryption
90
91 CM_ST_IDENT
92 -----------
93 Waiting for the remote random number or "MASTER", "SLAVE", "LOOPED" message.
94
95 CM_ST_KEYGEN
96 ------------
97 The master generates the key and waits for the key engine to finish.
98
99 CM_ST_KEYWAIT
100 -------------
101 The slave waits for the master to send the key.
102
103 CM_ST_CSKEY
104 -----------
105 The slave generates the session key and waits for the encryption engine to
106 finish.
107
108 CM_ST_CSWAIT
109 ------------
110 The master waits for the slave to send the crypted session key.
111
112 CM_ST_DSKEY
113 -----------
114 The master waits for the decryption engine to finish decryption of the session
115 key.
116
117 CM_ST_ACTIVE
118 ------------
119 The encryption is established.
120
121
122 Timouts
123 -------
124 CM_TO_IDENT     = waiting for the remote party to enable encryption
125 CM_TO_KEY       = waiting for key generation
126 CM_TO_CSKEY     = waiting for session key encryption
127 CM_TO_DSKEY     = waiting for session key decryption
128
129
130 Structure of message:
131 ---------------------
132
133 one octet message element
134 two octets element length (first octet = high-byte)
135 data as given in length
136
137 last element is 0
138 the message type is encoded as element
139
140
141 */
142
143 #include "main.h"
144 #ifdef CRYPTO
145 #include <openssl/rsa.h>
146 #endif
147
148
149 /* convert key string to binary key vector
150  * returns 0 if an error ocurred
151  */
152 unsigned char *crypt_key(unsigned char *key, int *binary_len)
153 {
154         static unsigned char binary_key[2048];
155         int i = 0;
156
157         binary_key[0] = '\0';
158
159         if (!key[0])
160                 return(NULL);
161
162         /* check for 0xXXXX... type of key */
163         if (!strncmp((char *)key, "0x", 2)) {
164                 key+=2;
165                 while(*key) {
166                         if (i == (int)sizeof(binary_key))
167                                 return(NULL);
168
169                         if (*key>='0' && *key<='9')
170                                 binary_key[i] = (*key-'0') << 8;
171                         else if (*key>='a' && *key<='f')
172                                 binary_key[i] = (*key-'a'+10) << 8;
173                         else if (*key>='A' && *key<='F')
174                                 binary_key[i] = (*key-'A'+10) << 8;
175                         else
176                                 return(NULL);
177                         key++;
178
179                         if (*key>='0' && *key<='9')
180                                 binary_key[i] += (*key - '0');
181                         else if (*key>='a' && *key<='f')
182                                 binary_key[i] += (*key - 'a' + 10);
183                         else if (*key>='A' && *key<='F')
184                                 binary_key[i] += (*key - 'A' + 10);
185                         else
186                                 return(NULL);
187                         key++;
188
189                         i++;
190                 }
191                 *binary_len = i;
192                 return(binary_key);
193         }
194
195         /* ascii key too long */
196         if (strlen((char *)key) >= sizeof((char *)binary_key))
197                 return(NULL);
198
199         memcpy(binary_key, key, strlen((char *)key));
200         *binary_len = strlen((char *)key);
201         return(binary_key);
202 }
203
204 /*
205  * support routine to get cpu speed
206  */
207 static unsigned int get_bogomips(void)
208 {
209         FILE *fp;
210         char buffer[64], *p;
211
212         fp = fopen("/proc/cpuinfo", "r");
213         if (!fp) {
214                 PERROR("Cannot access /proc/cpuinfo. Will not use cpuinfo for identification of pear\n");
215                 return(0);
216         }
217         fduse++;
218         buffer[sizeof(buffer-1)] = '\0';
219         while(GETLINE(buffer, fp)) {
220                 if (!!strncmp(buffer, "bogomips", 8))
221                         continue;
222                 if (!strchr(buffer, ':'))
223                         continue;
224                 p = strchr(buffer, ':')+1;
225                 while(*p == ' ')
226                         p++;
227                 if (strchr(p, '.'))
228                         *strchr(p, '.') = '\0';
229                 fclose(fp);
230                 fduse--;
231                 return(atoi(p));
232         }
233         fclose(fp);
234         fduse--;
235         PERROR("Cannot find 'bogomips' in /proc/cpuinfo. Will not use cpuinfo for identification of pear\n");
236         return(0);
237 }
238
239
240 /*
241  * crc 32 stuff
242  */
243 static unsigned int crc_reflect(unsigned int ref, char ch)
244 {
245         unsigned int value = 0;
246         int i;
247
248         i = 1;
249         while(i < ch+1) {
250                 if(ref & 1)
251                         value |= 1 << (ch - i);
252                 ref >>= 1;
253                 i++;
254         }
255         return(value);
256 }
257
258 static unsigned int crc32_table[256];
259 static int crc_initialized = 0;
260
261 void crc_init(void)
262 {
263         unsigned int ulPolynomial = 0x04c11db7;
264         int i, j;
265
266         i = 0;
267         while(i < 256) {
268                 crc32_table[i] = crc_reflect(i, 8) << 24;
269                 j = 0;
270                 while(j < 8) {
271                         crc32_table[i] = (crc32_table[i] << 1) ^ (crc32_table[i] & (1 << 31) ? ulPolynomial : 0);
272                         j++;
273                 }
274                 crc32_table[i] = crc_reflect(crc32_table[i], 32);
275                 i++;
276         }
277         crc_initialized = 1;
278 }
279
280 unsigned int crc32(unsigned char *data, int len)
281 {
282         unsigned int crc = 0xffffffff;
283
284         if (!crc_initialized)
285                 FATAL("crc not initialized, exitting...");
286
287         while (len--)
288                 crc = (crc >> 8) ^ crc32_table[(crc & 0xFF) ^ *data++];
289         return(crc^0xffffffff);
290 }
291
292
293 CM_ST_NAMES
294
295 /* give name of state */
296 static const char *statename(int state)
297 {
298         if (state>=0 && state<cm_st_num)
299                 return(cm_st_name[state]);
300         return("<<STATE UNKNOWN>>");
301 }
302
303 /*
304  * authentication key generation, encryption, decryption
305  */
306 struct auth_args {
307         class EndpointAppPBX *apppbx;
308         int     job;
309 };
310
311 static void *keyengine_child(void *arg)
312 {
313         struct auth_args *args = (struct auth_args *)arg;
314         class EndpointAppPBX *apppbx = args->apppbx;
315         int job = args->job;
316 #ifdef CRYPTO
317         RSA *rsa;
318         int exponent;
319         int i;
320 #endif
321
322         struct sched_param schedp;
323         int ret;
324
325         PDEBUG((DEBUG_EPOINT | DEBUG_CRYPT), "EPOINT(%d) child process started for using libcrypto\n", apppbx->ea_endpoint->ep_serial);
326
327         /* lower priority to keep pbx running fluently */
328         if (options.schedule > 0) {
329                 memset(&schedp, 0, sizeof(schedp));
330                 schedp.sched_priority = 0;
331                 ret = sched_setscheduler(0, SCHED_OTHER, &schedp);
332                 if (ret < 0) {
333                         PERROR("Scheduling to normal priority failed (errno = %d).\nExitting child process...\n", errno);
334                         goto done;
335                 }
336         }
337
338         switch(job) {
339                 /* generate rsa key pair */
340                 case CK_GENRSA_REQ:
341 #ifndef CRYPTO
342                 PERROR("Not compliled wiht crypto.\n");
343                 apppbx->e_crypt_keyengine_return = -1;
344 #else
345                 srandom(*((unsigned int *)mISDN_rand) ^ random());
346 //              exponent = (((random()<<1)|1) & 0x7f) + 0x80; /* odd */
347                 exponent = 65537;
348 //              if (exponent < 3) exponent = 3; /* >= 3 */
349                 rsa = RSA_generate_key(RSA_BITS, exponent, NULL, NULL);
350                 if (!rsa) {
351                         PERROR("Failed to generate rsa key pair.\n");
352                         apppbx->e_crypt_keyengine_return = -1;
353                         break;
354                 }
355                 ememuse++;
356                 apppbx->e_crypt_rsa_n_len = BN_num_bytes(rsa->n);
357                 if (apppbx->e_crypt_rsa_n_len > (int)sizeof(apppbx->e_crypt_rsa_n)) {
358                         kerror_buffer:
359                         PERROR("e_crypt_rsa_* too small for bignum.\n");
360                         apppbx->e_crypt_keyengine_return = -1;
361                         RSA_free(rsa);
362                         ememuse--;
363                         break;
364                 }
365                 BN_bn2bin(rsa->n, apppbx->e_crypt_rsa_n);
366                 apppbx->e_crypt_rsa_n_len = BN_num_bytes(rsa->n);
367                 if (apppbx->e_crypt_rsa_e_len > (int)sizeof(apppbx->e_crypt_rsa_e))
368                         goto kerror_buffer;
369                 BN_bn2bin(rsa->e, apppbx->e_crypt_rsa_e);
370                 apppbx->e_crypt_rsa_e_len = BN_num_bytes(rsa->e);
371                 if (apppbx->e_crypt_rsa_d_len > (int)sizeof(apppbx->e_crypt_rsa_d))
372                         goto kerror_buffer;
373                 BN_bn2bin(rsa->d, apppbx->e_crypt_rsa_d);
374                 apppbx->e_crypt_rsa_p_len = BN_num_bytes(rsa->p);
375                 if (apppbx->e_crypt_rsa_p_len > (int)sizeof(apppbx->e_crypt_rsa_p))
376                         goto kerror_buffer;
377                 BN_bn2bin(rsa->p, apppbx->e_crypt_rsa_p);
378                 apppbx->e_crypt_rsa_q_len = BN_num_bytes(rsa->q);
379                 if (apppbx->e_crypt_rsa_q_len > (int)sizeof(apppbx->e_crypt_rsa_q))
380                         goto kerror_buffer;
381                 BN_bn2bin(rsa->q, apppbx->e_crypt_rsa_q);
382                 apppbx->e_crypt_rsa_dmp1_len = BN_num_bytes(rsa->dmp1);
383                 if (apppbx->e_crypt_rsa_dmp1_len > (int)sizeof(apppbx->e_crypt_rsa_dmp1))
384                         goto kerror_buffer;
385                 BN_bn2bin(rsa->dmp1, apppbx->e_crypt_rsa_dmp1);
386                 apppbx->e_crypt_rsa_dmq1_len = BN_num_bytes(rsa->dmq1);
387                 if (apppbx->e_crypt_rsa_dmq1_len > (int)sizeof(apppbx->e_crypt_rsa_dmq1))
388                         goto kerror_buffer;
389                 BN_bn2bin(rsa->dmq1, apppbx->e_crypt_rsa_dmq1);
390                 apppbx->e_crypt_rsa_iqmp_len = BN_num_bytes(rsa->iqmp);
391                 if (apppbx->e_crypt_rsa_iqmp_len > (int)sizeof(apppbx->e_crypt_rsa_iqmp))
392                         goto kerror_buffer;
393                 BN_bn2bin(rsa->iqmp, apppbx->e_crypt_rsa_iqmp);
394                 PDEBUG(DEBUG_CRYPT, "gen: rsa n=%02x...\n", *apppbx->e_crypt_rsa_n);
395                 PDEBUG(DEBUG_CRYPT, "gen: rsa e=%02x...\n", *apppbx->e_crypt_rsa_e);
396                 PDEBUG(DEBUG_CRYPT, "gen: rsa d=%02x...\n", *apppbx->e_crypt_rsa_d);
397                 PDEBUG(DEBUG_CRYPT, "gen: rsa p=%02x...\n", *apppbx->e_crypt_rsa_p);
398                 PDEBUG(DEBUG_CRYPT, "gen: rsa q=%02x...\n", *apppbx->e_crypt_rsa_q);
399                 PDEBUG(DEBUG_CRYPT, "gen: rsa dmp1=%02x...\n", *apppbx->e_crypt_rsa_dmp1);
400                 PDEBUG(DEBUG_CRYPT, "gen: rsa dmq1=%02x...\n", *apppbx->e_crypt_rsa_dmq1);
401                 PDEBUG(DEBUG_CRYPT, "gen: rsa iqmp=%02x...\n", *apppbx->e_crypt_rsa_iqmp);
402                 apppbx->e_crypt_keyengine_return = 1;
403                 RSA_free(rsa);
404                 ememuse--;
405 #endif
406                 break;
407
408                 /* encrypt session key */
409                 case CK_CPTRSA_REQ:
410 #ifndef CRYPTO
411                 PERROR("No crypto lib.\n");
412                 apppbx->e_crypt_keyengine_return = -1;
413 #else
414                 /* generating session key */
415                 srandom(*((unsigned int *)mISDN_rand) ^ random());
416                 i = 0;
417                 while(i < 56) {
418                         apppbx->e_crypt_key[i] = random();
419                         apppbx->e_crypt_key[i] ^= mISDN_rand[random() & 0xff];
420                         i++;
421                 }
422                 apppbx->e_crypt_key_len = i;
423                 /* encrypt via rsa */
424                 rsa = RSA_new();
425                 if (!rsa) {
426                         PERROR("Failed to allocate rsa structure.\n");
427                         apppbx->e_crypt_keyengine_return = 1;
428                         break;
429                 }
430                 ememuse++;
431                 rsa->n = BN_new();
432                 rsa->e = BN_new();
433                 if (!rsa->n || !rsa->e) {
434                         PERROR("Failed to generate rsa structure.\n");
435                         apppbx->e_crypt_keyengine_return = -1;
436                         RSA_free(rsa);
437                         ememuse--;
438                         break;
439                 }
440                 if (!BN_bin2bn(apppbx->e_crypt_rsa_n, apppbx->e_crypt_rsa_n_len, rsa->n)) {
441                         eerror_bin2bn:
442                         PERROR("Failed to convert binary to bignum.\n");
443                         apppbx->e_crypt_keyengine_return = -1;
444                         RSA_free(rsa);
445                         ememuse--;
446                         break;
447                 }
448                 if ((apppbx->e_crypt_rsa_n_len*8) != BN_num_bits(rsa->n)) {
449                         PERROR("SOFTWARE API ERROR: length not equal stored data. (%d != %d)\n", apppbx->e_crypt_rsa_n_len*8, BN_num_bits(rsa->n));
450                         apppbx->e_crypt_keyengine_return = -1;
451                         RSA_free(rsa);
452                         ememuse--;
453                         break;
454                 }
455                 if (!BN_bin2bn(apppbx->e_crypt_rsa_e, apppbx->e_crypt_rsa_e_len, rsa->e))
456                         goto eerror_bin2bn;
457                 PDEBUG(DEBUG_CRYPT, "crypt: rsa n=%02x...\n", *apppbx->e_crypt_rsa_n);
458                 PDEBUG(DEBUG_CRYPT, "crypt: rsa e=%02x...\n", *apppbx->e_crypt_rsa_e);
459                 PDEBUG(DEBUG_CRYPT, "crypt: key =%02x%02x%02x%02x... (len=%d)\n", apppbx->e_crypt_key[0], apppbx->e_crypt_key[1], apppbx->e_crypt_key[2], apppbx->e_crypt_key[3], apppbx->e_crypt_key_len);
460                 apppbx->e_crypt_ckey_len = RSA_public_encrypt(
461                         apppbx->e_crypt_key_len,
462                         apppbx->e_crypt_key,
463                         apppbx->e_crypt_ckey,
464                         rsa,
465                         RSA_PKCS1_PADDING);
466                 PDEBUG(DEBUG_CRYPT, "crypt: ckey =%02x%02x%02x%02x... (len=%d)\n", apppbx->e_crypt_ckey[0], apppbx->e_crypt_ckey[1], apppbx->e_crypt_ckey[2], apppbx->e_crypt_ckey[3], apppbx->e_crypt_ckey_len);
467                 RSA_free(rsa);
468                 ememuse--;
469                 if (apppbx->e_crypt_ckey_len > 0)
470                         apppbx->e_crypt_keyengine_return = 1;
471                 else
472                         apppbx->e_crypt_keyengine_return = -1;
473 #endif
474                 break;
475
476                 /* decrypt session key */
477                 case CK_DECRSA_REQ:
478 #ifndef CRYPTO
479                 PERROR("No crypto lib.\n");
480                 apppbx->e_crypt_keyengine_return = -1;
481 #else
482                 rsa = RSA_new();
483                 if (!rsa) {
484                         PERROR("Failed to allocate rsa structure.\n");
485                         apppbx->e_crypt_keyengine_return = 1;
486                         break;
487                 }
488                 ememuse++;
489                 rsa->n = BN_new();
490                 rsa->e = BN_new();
491                 rsa->d = BN_new();
492                 rsa->p = BN_new();
493                 rsa->q = BN_new();
494                 rsa->dmp1 = BN_new();
495                 rsa->dmq1 = BN_new();
496                 rsa->iqmp = BN_new();
497                 if (!rsa->n || !rsa->e
498                  || !rsa->d || !rsa->p
499                  || !rsa->q || !rsa->dmp1
500                  || !rsa->dmq1 || !rsa->iqmp) {
501                         PERROR("Failed to generate rsa structure.\n");
502                         apppbx->e_crypt_keyengine_return = 1;
503                         RSA_free(rsa);
504                         ememuse--;
505                         break;
506                 }
507                 if (!BN_bin2bn(apppbx->e_crypt_rsa_n, apppbx->e_crypt_rsa_n_len, rsa->n)) {
508                         derror_bin2bn:
509                         PERROR("Failed to convert binary to bignum.\n");
510                         apppbx->e_crypt_keyengine_return = -1;
511                         RSA_free(rsa);
512                         ememuse--;
513                         break;
514                 }
515                 if (!BN_bin2bn(apppbx->e_crypt_rsa_e, apppbx->e_crypt_rsa_e_len, rsa->e))
516                         goto derror_bin2bn;
517                 if (!BN_bin2bn(apppbx->e_crypt_rsa_d, apppbx->e_crypt_rsa_d_len, rsa->d))
518                         goto derror_bin2bn;
519                 if (!BN_bin2bn(apppbx->e_crypt_rsa_p, apppbx->e_crypt_rsa_p_len, rsa->p))
520                         goto derror_bin2bn;
521                 if (!BN_bin2bn(apppbx->e_crypt_rsa_q, apppbx->e_crypt_rsa_q_len, rsa->q))
522                         goto derror_bin2bn;
523                 if (!BN_bin2bn(apppbx->e_crypt_rsa_dmp1, apppbx->e_crypt_rsa_dmp1_len, rsa->dmp1))
524                         goto derror_bin2bn;
525                 if (!BN_bin2bn(apppbx->e_crypt_rsa_dmq1, apppbx->e_crypt_rsa_dmq1_len, rsa->dmq1))
526                         goto derror_bin2bn;
527                 if (!BN_bin2bn(apppbx->e_crypt_rsa_iqmp, apppbx->e_crypt_rsa_iqmp_len, rsa->iqmp))
528                         goto derror_bin2bn;
529                 PDEBUG(DEBUG_CRYPT, "decrypt: ckey =%02x%02x%02x%02x... (len=%d)\n", apppbx->e_crypt_ckey[0], apppbx->e_crypt_ckey[1], apppbx->e_crypt_ckey[2], apppbx->e_crypt_ckey[3], apppbx->e_crypt_ckey_len);
530                 apppbx->e_crypt_key_len = RSA_private_decrypt(
531                         apppbx->e_crypt_ckey_len,
532                         apppbx->e_crypt_ckey,
533                         apppbx->e_crypt_key,
534                         rsa,
535                         RSA_PKCS1_PADDING);
536                 PDEBUG(DEBUG_CRYPT, "decrypt: key =%02x%02x%02x%02x... (len=%d)\n", apppbx->e_crypt_key[0], apppbx->e_crypt_key[1], apppbx->e_crypt_key[2], apppbx->e_crypt_key[3], apppbx->e_crypt_key_len);
537                 RSA_free(rsa);
538                 ememuse--;
539                 apppbx->e_crypt_keyengine_return = 1;
540 #endif
541                 break;
542
543                 default:
544                 PERROR("Unknown job %d\n", job);
545                 apppbx->e_crypt_keyengine_return = -1;
546         }
547
548         done:
549         PDEBUG((DEBUG_EPOINT | DEBUG_CRYPT), "child process done after using libcrypto with return value %d\n", apppbx->e_crypt_keyengine_return);
550
551         /* exit process */
552         if (--apppbx->ea_endpoint->ep_use <= 0)
553                 trigger_work(&apppbx->ea_endpoint->ep_delete);
554         FREE(args, sizeof(struct auth_args));
555         amemuse--;
556         return(NULL);
557 }
558
559 void EndpointAppPBX::cryptman_keyengine(int job)
560 {
561         struct auth_args *arg;
562         pthread_t tid;
563
564         if (e_crypt_keyengine_busy) {
565                 e_crypt_keyengine_return = -1;
566                 PERROR("engine currently busy.\n");
567                 return;
568         }
569
570         arg = (struct auth_args *)MALLOC(sizeof(struct auth_args));
571         arg->apppbx = this;
572         arg->job = job;
573         e_crypt_keyengine_return = 0;
574         e_crypt_keyengine_busy = job;
575
576         ea_endpoint->ep_use++;
577         if ((pthread_create(&tid, NULL, keyengine_child, arg)<0)) {
578                 ea_endpoint->ep_use--;
579                 PERROR("failed to create keyengine-thread.\n");
580                 e_crypt_keyengine_return = -1;
581                 return;
582         }
583         amemuse++;
584
585         PDEBUG((DEBUG_EPOINT | DEBUG_CRYPT), "send_mail(%d): child process created for doing crypto stuff\n", ea_endpoint->ep_serial);
586
587 }
588
589
590 /* handler for authentication (called by apppbx's handler)
591  */
592 int crypt_handler(struct lcr_timer *timer, void *instance, int index)
593 {
594         class EndpointAppPBX *ea = (class EndpointAppPBX *)instance;
595         struct timeval current_time;
596
597         if (ea->e_crypt_keyengine_busy) {
598                 if (ea->e_crypt_keyengine_return < 0) {
599                         ea->e_crypt_keyengine_busy = 0;
600                         ea->cryptman_message(CK_ERROR_IND, NULL, 0);
601                 } else
602                 if (ea->e_crypt_keyengine_return > 0) {
603                         switch(ea->e_crypt_keyengine_busy) {
604                                 case CK_GENRSA_REQ:
605                                 ea->e_crypt_keyengine_busy = 0;
606                                 ea->cryptman_message(CK_GENRSA_CONF, NULL, 0);
607                                 break;
608                                 case CK_CPTRSA_REQ:
609                                 ea->e_crypt_keyengine_busy = 0;
610                                 ea->cryptman_message(CK_CPTRSA_CONF, NULL, 0);
611                                 break;
612                                 case CK_DECRSA_REQ:
613                                 ea->e_crypt_keyengine_busy = 0;
614                                 ea->cryptman_message(CK_DECRSA_CONF, NULL, 0);
615                                 break;
616                         }
617                 }
618         }
619
620         /* check for event, make next event */
621         gettimeofday(&current_time, NULL);
622         if (ea->e_crypt_timeout_sec) if (ea->e_crypt_timeout_sec<current_time.tv_sec || (ea->e_crypt_timeout_sec==current_time.tv_sec && ea->e_crypt_timeout_usec<current_time.tv_usec)) {
623                 ea->e_crypt_timeout_sec = 0;
624                 ea->e_crypt_timeout_usec = 0;
625                 ea->cryptman_message(CT_TIMEOUT, NULL, 0);
626         }
627
628         /* trigger until state is 0 */
629         if (ea->e_crypt_state != CM_ST_NULL)
630                 schedule_timer(&ea->e_crypt_handler, 0, 100000);
631
632         return 0;
633 }
634
635
636 /*
637  * process message to the crypt manager
638  */
639 /* remote peer sends ident request */
640 void EndpointAppPBX::cr_ident(int message, unsigned char *param, int len)
641 {
642         unsigned char buf[4], *p;
643         unsigned int bogomips = 0, ran;
644         int l;
645
646         l = CM_SIZEOFINF(CM_INFO_RANDOM);
647         if (l != 4) {
648                 PDEBUG(DEBUG_CRYPT, "EPOINT(%d) missing (or corrupt) random number, ignoring (len = %d)\n", ea_endpoint->ep_serial, l);
649                 return;
650         }
651         p = CM_GETINF(CM_INFO_RANDOM, buf);
652         ran = (p[0]<<24) + (p[1]<<16) + (p[2]<<8) + p[3];
653         l = CM_SIZEOFINF(CM_INFO_BOGOMIPS);
654         if (l != 4) {
655                 PDEBUG(DEBUG_CRYPT, "EPOINT(%d) missing (or corrupt) random bogomips, just comparing random (len = %d)\n", ea_endpoint->ep_serial, l);
656                 goto compare_random;
657         }
658         p = CM_GETINF(CM_INFO_BOGOMIPS, buf);
659         bogomips = (p[0]<<24) + (p[1]<<16) + (p[2]<<8) + p[3];
660         if (e_crypt_bogomips > bogomips) {
661                 PDEBUG(DEBUG_CRYPT, "EPOINT(%d) our cpu is faster, so we are master (%d > %d)\n", ea_endpoint->ep_serial, e_crypt_bogomips, bogomips);
662                 cr_master(message, NULL, 0);
663                 return;
664         }
665         if (e_crypt_bogomips < bogomips) {
666                 PDEBUG(DEBUG_CRYPT, "EPOINT(%d) our cpu is slower, so we are slave (%d < %d)\n", ea_endpoint->ep_serial, e_crypt_bogomips, bogomips);
667                 cr_slave(message, NULL, 0);
668                 return;
669         }
670         PDEBUG(DEBUG_CRYPT, "EPOINT(%d) our cpu is equal speed, so we check for random value (%d == %d)\n", ea_endpoint->ep_serial, e_crypt_bogomips, bogomips);
671         compare_random:
672         /* bogomips are equal, so we compare */
673         if (e_crypt_random > ran) {
674                 PDEBUG(DEBUG_CRYPT, "EPOINT(%d) our random value is greater, so we are master (%d > %d)\n", ea_endpoint->ep_serial, e_crypt_random, ran);
675                 cr_master(message, NULL, 0);
676                 return;
677         }
678         if (e_crypt_random < ran) {
679                 PDEBUG(DEBUG_CRYPT, "EPOINT(%d) our random value is smaller, so we are slave (%d < %d)\n", ea_endpoint->ep_serial, e_crypt_random, ran);
680                 cr_slave(message, NULL, 0);
681                 return;
682         }
683         PDEBUG(DEBUG_CRYPT, "EPOINT(%d) random values are equal, so we are looped (%d == %d)\n", ea_endpoint->ep_serial, e_crypt_random, ran);
684         cr_looped(message, NULL, 0);
685 }
686
687 /* key-exchange activation by the user */
688 void EndpointAppPBX::cr_activate(int message, unsigned char *param, int len)
689 {
690         unsigned char buf[128] = "";
691         unsigned char msg;
692         unsigned char bogomips[4], ran[4];
693         struct timeval current_time;
694
695         /* activate listener */
696         cryptman_msg2crengine(CR_LISTEN_REQ, NULL, 0);
697         /* send ident message */
698         msg = CMSG_IDENT;
699         CM_ADDINF(CM_INFO_MESSAGE, 1, &msg);
700         /* random number element */
701         gettimeofday(&current_time, NULL);
702         srandom(current_time.tv_sec ^ current_time.tv_usec ^ random());
703         e_crypt_random = random();
704         ran[0] = e_crypt_random >> 24;
705         ran[1] = e_crypt_random >> 16;
706         ran[2] = e_crypt_random >> 8;
707         ran[3] = e_crypt_random;
708         CM_ADDINF(CM_INFO_RANDOM, 4, ran);
709         /* cpu speed element */
710         e_crypt_bogomips = get_bogomips();
711         if (e_crypt_bogomips > 0) {
712                 bogomips[0] = e_crypt_bogomips >> 24;
713                 bogomips[1] = e_crypt_bogomips >> 16;
714                 bogomips[2] = e_crypt_bogomips >> 8;
715                 bogomips[3] = e_crypt_bogomips;
716                 CM_ADDINF(CM_INFO_BOGOMIPS, 4, bogomips);
717         }
718         /* send ident message */
719         cryptman_msg2peer(buf);
720         /* change state */
721         cryptman_state(CM_ST_IDENT);
722         /* set timeout */
723         cryptman_timeout(CM_TO_IDENT);
724 }
725
726 /* deactivation by the user */
727 void EndpointAppPBX::cr_deactivate(int message, unsigned char *param, int len)
728 {
729         unsigned char buf[128] = "";
730         unsigned char msg;
731
732         /* deactivate listener (if not already) */
733         cryptman_msg2crengine(CR_UNLISTEN_REQ, NULL, 0);
734         /* message */
735         msg = CMSG_ABORT;
736         CM_ADDINF(CM_INFO_MESSAGE, 1, &msg);
737         cryptman_msg2peer(buf);
738         /* deactivate encryption */
739         cryptman_msg2crengine(CC_DACT_REQ, NULL, 0);
740         /* change state */
741         cryptman_state(CM_ST_NULL);
742         /* send message to user */
743         cryptman_msg2user(CU_DACT_CONF, "Deactivated");
744 }
745
746 /* remote peer tells us to be master */
747 void EndpointAppPBX::cr_master(int message, unsigned char *param, int len)
748 {
749         unsigned char buf[128] = "";
750         unsigned char msg;
751
752         /* change to master state */
753         cryptman_state(CM_ST_KEYGEN);
754         if (message == CP_IDENT) {
755                 /* send you-are-slave-message */
756                 msg = CMSG_SLAVE;
757                 CM_ADDINF(CM_INFO_MESSAGE, 1, &msg);
758                 cryptman_msg2peer(buf);
759         }
760         /* start generation of key */
761         cryptman_keyengine(CK_GENRSA_REQ);
762         /* disable timeout */
763         cryptman_timeout(0);
764         /* send message to user */
765         cryptman_msg2user(CU_INFO_IND, "Master");
766 }
767
768 /* remote peer tells us to be slave */
769 void EndpointAppPBX::cr_slave(int message, unsigned char *param, int len)
770 {
771         unsigned char buf[128] = "";
772         unsigned char msg;
773
774         /* change to slave state */
775         cryptman_state(CM_ST_KEYWAIT);
776         if (message == CP_IDENT) {
777                 /* send you-are-slave-message */
778                 msg = CMSG_MASTER;
779                 /* message */
780                 CM_ADDINF(CM_INFO_MESSAGE, 1, &msg);
781                 cryptman_msg2peer(buf);
782         }
783         /* set timeout */
784         cryptman_timeout(CM_TO_PUBKEY);
785         /* send message to user */
786         cryptman_msg2user(CU_INFO_IND, "Slave");
787 }
788
789 /* remote peer tells us about loop */
790 void EndpointAppPBX::cr_looped(int message, unsigned char *param, int len)
791 {
792         unsigned char buf[128] = "";
793         unsigned char msg;
794
795         /* change to idle state */
796         cryptman_state(CM_ST_NULL);
797         /* deactivate listener */
798         cryptman_msg2crengine(CR_UNLISTEN_REQ, NULL, 0);
799         if (message == CP_IDENT) {
800                 /* send looped */
801                 msg = CMSG_LOOPED;
802                 /* message */
803                 CM_ADDINF(CM_INFO_MESSAGE, 1, &msg);
804                 cryptman_msg2peer(buf);
805         }
806         /* disable timeout */
807         cryptman_timeout(0);
808         /* send message to user */
809         cryptman_msg2user(CU_ERROR_IND, "Loop Detected");
810 }
811
812 /* abort */
813 void EndpointAppPBX::cr_abort(int message, unsigned char *param, int len)
814 {
815         /* if already encrypting */
816         if (e_crypt_state==CM_ST_WAIT_CRYPT
817          || e_crypt_state==CM_ST_SWAIT
818          || e_crypt_state==CM_ST_ACTIVE) {
819                 /* deactivate blowfish */
820                 cryptman_msg2crengine(CC_DACT_REQ, NULL, 0);
821         }
822         /* change to idle state */
823         cryptman_state(CM_ST_NULL);
824         /* deactivate listener */
825         cryptman_msg2crengine(CR_UNLISTEN_REQ, NULL, 0);
826         /* disable timeout */
827         cryptman_timeout(0);
828         /* send message to user */
829         if (message == CT_TIMEOUT)
830                 cryptman_msg2user(CU_ERROR_IND, "Timeout");
831         else if (message == CP_ABORT)
832                 cryptman_msg2user(CU_ERROR_IND, "Remote Abort");
833         else
834                 cryptman_msg2user(CU_DACT_IND, NULL);
835 }
836
837 /* abort but wait for engine to release*/
838 void EndpointAppPBX::cr_abort_engine(int message, unsigned char *param, int len)
839 {
840         /* change to release state */
841         cryptman_state(CM_ST_RELEASE);
842         /* deactivate listener */
843         cryptman_msg2crengine(CR_UNLISTEN_REQ, NULL, 0);
844         /* disable timeout */
845         cryptman_timeout(0);
846         /* send message to user */
847         if (message == CT_TIMEOUT)
848                 cryptman_msg2user(CU_ERROR_IND, "Timeout");
849         else if (message == CP_ABORT)
850                 cryptman_msg2user(CU_ERROR_IND, "Remote Abort");
851         else
852                 cryptman_msg2user(CU_DACT_IND, NULL);
853 }
854
855 /* abort and disable crypt engine */
856 void EndpointAppPBX::cr_abort_wait(int message, unsigned char *param, int len)
857 {
858         /* change to idle state */
859         cryptman_state(CM_ST_NULL);
860         /* deactivate listener (if not already) */
861         cryptman_msg2crengine(CR_UNLISTEN_REQ, NULL, 0);
862         /* deactivate blowfish */
863         cryptman_msg2crengine(CC_DACT_REQ, NULL, 0);
864         /* disable timeout */
865         cryptman_timeout(0);
866         /* send message to user */
867         if (message == CT_TIMEOUT)
868                 cryptman_msg2user(CU_ERROR_IND, "Timeout");
869         else if (message == CP_ABORT)
870                 cryptman_msg2user(CU_ERROR_IND, "Remote Abort");
871         else
872                 cryptman_msg2user(CU_DACT_IND, NULL);
873 }
874
875 /* key engine tells us that the rsa is ready */
876 void EndpointAppPBX::cr_genrsa(int message, unsigned char *param, int len)
877 {
878         unsigned char buf[1024] = "";
879         unsigned char msg;
880
881         /* change to wait for crypted session key state */
882         cryptman_state(CM_ST_CSWAIT);
883         /* message */
884         msg = CMSG_PUBKEY;
885         CM_ADDINF(CM_INFO_MESSAGE, 1, &msg);
886         CM_ADDINF(CM_INFO_PUBKEY, e_crypt_rsa_n_len, &e_crypt_rsa_n);
887         CM_ADDINF(CM_INFO_PUBEXPONENT, e_crypt_rsa_e_len, &e_crypt_rsa_e);
888         cryptman_msg2peer(buf);
889         /* set timeout */
890         cryptman_timeout(CM_TO_CSKEY);
891 }
892
893 /* our engine has a key error */
894 void EndpointAppPBX::cr_keyerror(int message, unsigned char *param, int len)
895 {
896         unsigned char buf[128] = "";
897         unsigned char msg;
898
899         /* change to idle state */
900         cryptman_state(CM_ST_NULL);
901         /* deactivate listener */
902         cryptman_msg2crengine(CR_UNLISTEN_REQ, NULL, 0);
903         /* message */
904         msg = CMSG_ABORT;
905         CM_ADDINF(CM_INFO_MESSAGE, 1, &msg);
906         cryptman_msg2peer(buf);
907         /* send message to user */
908         cryptman_msg2user(CU_ERROR_IND, "Local Key Error");
909 }
910
911 /* remote sends us the rsa public key */
912 void EndpointAppPBX::cr_pubkey(int message, unsigned char *param, int len)
913 {
914         unsigned char buf[128] = "";
915         unsigned char msg = CMSG_ABORT;
916         int l;
917
918         l = CM_SIZEOFINF(CM_INFO_PUBKEY);
919         if (l<1 || l>(int)sizeof(e_crypt_rsa_n)) {
920                 size_error:
921                 /* change to idle state */
922                 cryptman_state(CM_ST_NULL);
923                 /* deactivate listener */
924                 cryptman_msg2crengine(CR_UNLISTEN_REQ, NULL, 0);
925                 /* message */
926                 CM_ADDINF(CM_INFO_MESSAGE, 1, &msg);
927                 cryptman_msg2peer(buf);
928                 /* send message to user */
929                 cryptman_msg2user(CU_ERROR_IND, "Remote Key Error");
930                 return;
931         }
932         CM_GETINF(CM_INFO_PUBKEY, e_crypt_rsa_n);
933         e_crypt_rsa_n_len = l;
934         l = CM_SIZEOFINF(CM_INFO_PUBEXPONENT);
935         if (l<1 || l>(int)sizeof(e_crypt_rsa_e))
936                 goto size_error;
937         CM_GETINF(CM_INFO_PUBEXPONENT, e_crypt_rsa_e);
938         e_crypt_rsa_e_len = l;
939         /* change to generating encrypted sessnion key state */
940         cryptman_state(CM_ST_CSKEY);
941         /* start generation of crypted session key */
942         cryptman_keyengine(CK_CPTRSA_REQ);
943         /* disable timeout */
944         cryptman_timeout(0);
945 }
946
947 /* key engine tells us that the crypted session key is ready */
948 void EndpointAppPBX::cr_cptrsa(int message, unsigned char *param, int len)
949 {
950         unsigned char buf[1024] = "";
951         unsigned char msg = CMSG_CSKEY;
952
953         /* change to wait for crypt engine state */
954         cryptman_state(CM_ST_WAIT_DELAY);
955         /* message */
956         CM_ADDINF(CM_INFO_MESSAGE, 1, &msg);
957         CM_ADDINF(CM_INFO_CSKEY, e_crypt_ckey_len, &e_crypt_ckey);
958         cryptman_msg2peer(buf);
959         /* deactivate listener */
960         cryptman_msg2crengine(CR_UNLISTEN_REQ, NULL, 0);
961         /* timeout 1 sec */
962         cryptman_timeout(1);
963 }
964
965 /* now we waited for the remote to receive and decrypt the session key */
966 void EndpointAppPBX::cr_waitdelay(int message, unsigned char *param, int len)
967 {
968         /* change to wait for crypt engine state */
969         cryptman_state(CM_ST_WAIT_CRYPT);
970         /* disable timeout */
971         cryptman_timeout(0);
972         /* send message to crypt engine */
973         cryptman_msg2crengine(CC_ACTBF_REQ, e_crypt_key, e_crypt_key_len);
974 }
975
976 /* remote sends us the crypted session key */
977 void EndpointAppPBX::cr_cskey(int message, unsigned char *param, int len)
978 {
979         unsigned char buf[128] = "";
980         unsigned char msg = CMSG_ABORT;
981         int l;
982
983         /* disable timeout */
984         cryptman_timeout(0);
985         l = CM_SIZEOFINF(CM_INFO_CSKEY);
986         if (l<1 || l>(int)sizeof(e_crypt_ckey)) {
987                 /* change to idle state */
988                 cryptman_state(CM_ST_NULL);
989                 /* deactivate listener */
990                 cryptman_msg2crengine(CR_UNLISTEN_REQ, NULL, 0);
991                 /* message */
992                 CM_ADDINF(CM_INFO_MESSAGE, 1, &msg);
993                 cryptman_msg2peer(buf);
994                 /* send message to user */
995                 cryptman_msg2user(CU_ERROR_IND, "Remote Key Error");
996                 return;
997         }
998         CM_GETINF(CM_INFO_CSKEY, e_crypt_ckey);
999         e_crypt_ckey_len = l;
1000         /* change to generating decrypted session key state */
1001         cryptman_state(CM_ST_SESSION);
1002         /* start generation of decrypted session key */
1003         cryptman_keyengine(CK_DECRSA_REQ);
1004 }
1005
1006 /* key engine tells us that the decrypted session key is ready */
1007 void EndpointAppPBX::cr_decrsa(int message, unsigned char *param, int len)
1008 {
1009         /* change to wait for crypt engine state */
1010         cryptman_state(CM_ST_WAIT_CRYPT);
1011         /* deactivate listener */
1012         cryptman_msg2crengine(CR_UNLISTEN_REQ, NULL, 0);
1013         /* send message to crypt engine */
1014         cryptman_msg2crengine(CC_ACTBF_REQ, e_crypt_key, e_crypt_key_len);
1015 }
1016
1017 /* blowfish now active */
1018 void EndpointAppPBX::cr_bfactive(int message, unsigned char *param, int len)
1019 {
1020         char text[64];
1021
1022         /* change to active state */
1023         cryptman_state(CM_ST_ACTIVE);
1024         /* send message to user */
1025         SPRINT(text, "PUB %02x%02x %02x%02x %02x%02x %02x%02x", e_crypt_key[0], e_crypt_key[1], e_crypt_key[2], e_crypt_key[3], e_crypt_key[4], e_crypt_key[5], e_crypt_key[6], e_crypt_key[7]);
1026         cryptman_msg2user(CU_ACTK_CONF, text);
1027 }
1028
1029 /* our crypt engine sends an error */
1030 void EndpointAppPBX::cr_crypterror(int message, unsigned char *param, int len)
1031 {
1032         unsigned char buf[128] = "";
1033         unsigned char msg = CMSG_ABORT;
1034
1035         /* change to idle state */
1036         cryptman_state(CM_ST_NULL);
1037         /* deactivate listener */
1038         cryptman_msg2crengine(CR_UNLISTEN_REQ, NULL, 0);
1039         /* message */
1040         CM_ADDINF(CM_INFO_MESSAGE, 1, &msg);
1041         cryptman_msg2peer(buf);
1042         /* send message to user */
1043         cryptman_msg2user(CU_ERROR_IND, "Blowfish Error");
1044 }
1045
1046 /* engine is done, now we are done with release */
1047 void EndpointAppPBX::cr_release(int message, unsigned char *param, int len)
1048 {
1049         /* change to idle state */
1050         cryptman_state(CM_ST_NULL);
1051 }
1052
1053 /* activate using shared key */
1054 void EndpointAppPBX::cr_sactivate(int message, unsigned char *param, int len)
1055 {
1056         /* change to 'wait for crypt engine' state */
1057         cryptman_state(CM_ST_SWAIT);
1058         /* disable timeout */
1059         cryptman_timeout(0);
1060         /* send key to crypt engine */
1061         cryptman_msg2crengine(CC_ACTBF_REQ, param, len);
1062 }
1063
1064 /* share key deactivation by the user */
1065 void EndpointAppPBX::cr_sdeactivate(int message, unsigned char *param, int len)
1066 {
1067         /* deactivate encryption */
1068         cryptman_msg2crengine(CC_DACT_REQ, NULL, 0);
1069         /* change state */
1070         cryptman_state(CM_ST_NULL);
1071         /* send message to user */
1072         cryptman_msg2user(CU_DACT_CONF, NULL);
1073 }
1074
1075 /* shared key abort */
1076 void EndpointAppPBX::cr_sabort(int message, unsigned char *param, int len)
1077 {
1078         /* change to idle state */
1079         cryptman_state(CM_ST_NULL);
1080         /* send message to user */
1081         cryptman_msg2user(CU_DACT_IND, "Deactivated");
1082 }
1083
1084 /* shared key: our crypt engine sends an error */
1085 void EndpointAppPBX::cr_scrypterror(int message, unsigned char *param, int len)
1086 {
1087         /* change to idle state */
1088         cryptman_state(CM_ST_NULL);
1089         /* send message to user */
1090         cryptman_msg2user(CU_ERROR_IND, "Blowfish Error");
1091 }
1092
1093 /* blowfish now active */
1094 void EndpointAppPBX::cr_sbfactive(int message, unsigned char *param, int len)
1095 {
1096         char text[64];
1097
1098         /* change to active state */
1099         cryptman_state(CM_ST_SACTIVE);
1100         /* send message to user */
1101         SPRINT(text, "Call Secure");
1102         cryptman_msg2user(CU_ACTS_CONF, text);
1103 }
1104
1105 /* user requests info */
1106 void EndpointAppPBX::cr_info(int message, unsigned char *param, int len)
1107 {
1108         /* send message to user */
1109         cryptman_msg2user(CU_INFO_CONF, e_crypt_info);
1110 }
1111
1112
1113 CM_MSG_NAMES
1114
1115 void EndpointAppPBX::cryptman_message(int message, unsigned char *param, int len)
1116 {
1117         const char *msgtext = "<<UNKNOWN MESSAGE>>";
1118
1119         if (message>=0 && message<cm_msg_num)
1120                 msgtext = cm_msg_name[message];
1121
1122         PDEBUG(DEBUG_CRYPT, "EPOINT(%d) CRYPT MANAGER in state '%s' received message: %s len: %d\n", ea_endpoint->ep_serial, statename(e_crypt_state), msgtext, len);
1123
1124         /* all states */
1125         if (message == CU_INFO_REQ)
1126                 { cr_info(message, param, len); return; }
1127
1128         switch(e_crypt_state) {
1129                 /* in idle state */
1130                 case CM_ST_NULL:
1131                 if (message == CU_ACTK_REQ) /* request key-exchange encryption */
1132                         { cr_activate(message, param, len); return; }
1133                 if (message == CU_ACTS_REQ) /* request shared encryption */
1134                         { cr_sactivate(message, param, len); return; }
1135                 break;
1136
1137                 /* identifying state */
1138                 case CM_ST_IDENT:
1139                 if (message == CP_IDENT) /* request encryption */
1140                         { cr_ident(message, param, len); return; }
1141                 if (message == CP_SLAVE) /* we are slave */
1142                         { cr_slave(message, param, len); return; }
1143                 if (message == CP_MASTER) /* we are master */
1144                         { cr_master(message, param, len); return; }
1145                 if (message == CP_LOOPED) /* we are looped */
1146                         { cr_looped(message, param, len); return; }
1147                 if (message == CI_DISCONNECT_IND /* request aborting */
1148                  || message == CT_TIMEOUT /* timeout */
1149                  || message == CP_ABORT) /* request aborting */
1150                         { cr_abort(message, param, len); return; }
1151                 break;
1152
1153                 /* generating public key state */
1154                 case CM_ST_KEYGEN:
1155                 if (message == CK_GENRSA_CONF) /* public key is done */
1156                         { cr_genrsa(message, param, len); return; }
1157                 if (message == CK_ERROR_IND) /* key failed */
1158                         { cr_keyerror(message, param, len); return; }
1159                 if (message == CI_DISCONNECT_IND /* request aborting */
1160                  || message == CP_ABORT) /* request aborting */
1161                         { cr_abort_engine(message, param, len); return; }
1162                 break;
1163
1164                 /* waiting for public key state */
1165                 case CM_ST_KEYWAIT:
1166                 if (message == CP_PUBKEY) /* getting public key from remote */
1167                         { cr_pubkey(message, param, len); return; }
1168                 if (message == CI_DISCONNECT_IND /* request aborting */
1169                  || message == CT_TIMEOUT /* timeout */
1170                  || message == CP_ABORT) /* request aborting */
1171                         { cr_abort(message, param, len); return; }
1172                 break;
1173
1174                 /* generating crypted session key state */
1175                 case CM_ST_CSKEY:
1176                 if (message == CK_CPTRSA_CONF) /* crypted session key is done */
1177                         { cr_cptrsa(message, param, len); return; }
1178                 if (message == CK_ERROR_IND) /* key failed */
1179                         { cr_keyerror(message, param, len); return; }
1180                 if (message == CI_DISCONNECT_IND /* request aborting */
1181                  || message == CP_ABORT) /* request aborting */
1182                         { cr_abort_engine(message, param, len); return; }
1183                 break;
1184
1185                 /* waiting for crypted session key state */
1186                 case CM_ST_CSWAIT:
1187                 if (message == CP_CSKEY) /* getting crypted session key from remote */
1188                         { cr_cskey(message, param, len); return; }
1189                 if (message == CI_DISCONNECT_IND /* request aborting */
1190                  || message == CT_TIMEOUT /* timeout */
1191                  || message == CP_ABORT) /* request aborting */
1192                         { cr_abort(message, param, len); return; }
1193                 break;
1194
1195                 /* generating decrypted session key state */
1196                 case CM_ST_SESSION:
1197                 if (message == CK_DECRSA_CONF) /* decrypted is done */
1198                         { cr_decrsa(message, param, len); return; }
1199                 if (message == CK_ERROR_IND) /* key failed */
1200                         { cr_keyerror(message, param, len); return; }
1201                 if (message == CI_DISCONNECT_IND /* request aborting */
1202                  || message == CP_ABORT) /* request aborting */
1203                         { cr_abort_engine(message, param, len); return; }
1204                 break;
1205
1206                 /* wait encryption on state */
1207                 case CM_ST_WAIT_DELAY:
1208                 if (message == CT_TIMEOUT) /* timeout of delay */
1209                         { cr_waitdelay(message, param, len); return; }
1210                 if (message == CC_ERROR_IND) /* encrpytion error */
1211                         { cr_crypterror(message, param, len); return; }
1212                 if (message == CI_DISCONNECT_IND /* request aborting */
1213                  || message == CP_ABORT) /* request aborting */
1214                         { cr_abort_wait(message, param, len); return; }
1215                 break;
1216
1217                 /* wait encryption on state */
1218                 case CM_ST_WAIT_CRYPT:
1219                 if (message == CC_ACTBF_CONF) /* encrpytion active */
1220                         { cr_bfactive(message, param, len); return; }
1221                 if (message == CC_ERROR_IND) /* encrpytion error */
1222                         { cr_crypterror(message, param, len); return; }
1223                 if (message == CI_DISCONNECT_IND /* request aborting */
1224                  || message == CP_ABORT) /* request aborting */
1225                         { cr_abort_wait(message, param, len); return; }
1226                 break;
1227
1228                 /* active state */
1229                 case CM_ST_ACTIVE:
1230                 if (message == CU_DACT_REQ) /* deactivating encryption */
1231                         { cr_deactivate(message, param, len); return; }
1232                 if (message == CI_DISCONNECT_IND /* request aborting */
1233                  || message == CP_ABORT) /* request aborting */
1234                         { cr_abort(message, param, len); return; }
1235                 break;
1236
1237
1238                 /* engine done after abort state */
1239                 case CM_ST_RELEASE:
1240                 if (message == CK_GENRSA_CONF /* engine done */
1241                  || message == CK_CPTRSA_CONF /* engine done */
1242                  || message == CK_DECRSA_CONF /* engine done */
1243                  || message == CK_ERROR_IND) /* engine error */
1244                         { cr_release(message, param, len); return; }
1245                 break;
1246
1247                 /* shared active state */
1248                 case CM_ST_SACTIVE:
1249                 if (message == CU_DACT_REQ) /* deactivating encryption */
1250                         { cr_sdeactivate(message, param, len); return; }
1251                 if (message == CI_DISCONNECT_IND) /* request aborting */
1252                         { cr_sabort(message, param, len); return; }
1253                 break;
1254
1255                 /* wait shared encryption on state */
1256                 case CM_ST_SWAIT:
1257                 if (message == CC_ACTBF_CONF) /* encrpytion active */
1258                         { cr_sbfactive(message, param, len); return; }
1259                 if (message == CC_ERROR_IND) /* encrpytion error */
1260                         { cr_scrypterror(message, param, len); return; }
1261                 if (message == CI_DISCONNECT_IND) /* request aborting */
1262                         { cr_sabort(message, param, len); return; }
1263                 break;
1264
1265         }
1266
1267         PDEBUG(DEBUG_CRYPT, "message not handled in state %d\n", e_crypt_state);
1268 }
1269
1270
1271 /*
1272  * analyze the message element within the received message from peer and call 'cryptman_message'
1273  */
1274 void EndpointAppPBX::cryptman_msg2man(unsigned char *param, int len)
1275 {
1276         unsigned char *p;
1277         unsigned char msg;
1278         int i, l;
1279
1280         /* check if frame is correct */
1281         PDEBUG(DEBUG_CRYPT, "EPOINT(%d) message from peer to crypt_manager.\n", ea_endpoint->ep_serial);
1282         if (len == 0) {
1283                 PDEBUG(DEBUG_CRYPT, "ignoring message with 0-length.\n");
1284                 return;
1285         }
1286         i = 0;
1287         p = param;
1288         while(*p) {
1289                 if (i == len) {
1290                         PDEBUG(DEBUG_CRYPT, "end of message without 0-termination.\n");
1291                         return;
1292                 }
1293                 if (i+3 > len) {
1294                         PDEBUG(DEBUG_CRYPT, "message with element size, outside the frame length.\n");
1295                         return;
1296                 }
1297                 l = (p[1]<<8) + p[2];
1298 //              PDEBUG(DEBUG_CRYPT, "   inf %d (len = %d)\n", *p, l);
1299                 if (i+3+l > len) {
1300                         PDEBUG(DEBUG_CRYPT, "message with element data, outside the frame length.\n");
1301                         return;
1302                 }
1303                 i += l + 3;
1304                 p += l + 3;
1305         }
1306         if (i+1 != len) {
1307                 PDEBUG(DEBUG_CRYPT, "warning: received null-element before end of frame.\n");
1308         }
1309
1310         l = CM_SIZEOFINF(CM_INFO_MESSAGE);
1311         if (l != 1) {
1312                 PDEBUG(DEBUG_CRYPT, "received message without (valid) message element (len = %d)\n", len);
1313                 return;
1314         }
1315         CM_GETINF(CM_INFO_MESSAGE, &msg);
1316         switch (msg) {
1317                 case CMSG_IDENT:
1318                 cryptman_message(CP_IDENT, param, len);
1319                 break;
1320                 case CMSG_SLAVE:
1321                 cryptman_message(CP_SLAVE, param, len);
1322                 break;
1323                 case CMSG_MASTER:
1324                 cryptman_message(CP_MASTER, param, len);
1325                 break;
1326                 case CMSG_PUBKEY:
1327                 cryptman_message(CP_PUBKEY, param, len);
1328                 break;
1329                 case CMSG_CSKEY:
1330                 cryptman_message(CP_CSKEY, param, len);
1331                 break;
1332                 case CMSG_ABORT:
1333                 cryptman_message(CP_ABORT, param, len);
1334                 break;
1335                 default:
1336                 PDEBUG(DEBUG_CRYPT, "received unknown message element %d\n", msg);
1337         }
1338 }
1339
1340 /* add information element to buffer
1341  */
1342 void EndpointAppPBX::cryptman_addinf(unsigned char *buf, int buf_size, int element, int len, void *data)
1343 {
1344         int l;
1345
1346         /* skip what we already have in the buffer */
1347         while (buf[0]) {
1348                 l = (buf[1]<<8) + buf[2];
1349                 if (l >= buf_size-3) {
1350                         PERROR("EPOINT(%d) buffer overflow while adding information to peer message.\n", ea_endpoint->ep_serial);
1351                         return;
1352                 }
1353                 buf_size -= l + 3;
1354                 buf += l + 3;
1355         }
1356         /* check if we have not enough space to add element including id, len, data, and the null-termination */
1357         if (len+4 > buf_size) {
1358                 PERROR("EPOINT(%d) cannot add element to message, because buffer would overflow.\n", ea_endpoint->ep_serial);
1359                 return;
1360         }
1361         buf[0] = element;
1362         buf[1] = len >> 8;
1363         buf[2] = len;
1364         memcpy(buf+3, data, len);
1365 }
1366
1367
1368 /* get size of element in buffer
1369  */
1370 int EndpointAppPBX::cryptman_sizeofinf(unsigned char *buf, int element)
1371 {
1372         int l;
1373
1374         /* skip what we already have in the buffer */
1375         while (buf[0]) {
1376                 l = (buf[1]<<8) + buf[2];
1377                 if (buf[0] == element)
1378                         return(l);
1379                 buf += l + 3;
1380         }
1381         return(-1);
1382 }
1383
1384
1385 /* get information element from buffer
1386  */
1387 unsigned char *EndpointAppPBX::cryptman_getinf(unsigned char *buf, int element, unsigned char *to)
1388 {
1389         int l;
1390
1391         /* skip what we already have in the buffer */
1392         while (buf[0]) {
1393                 l = (buf[1]<<8) + buf[2];
1394                 if (buf[0] == element) {
1395                         memcpy(to, buf+3, l);
1396                         return(to);
1397                 }
1398                 buf += l + 3;
1399         }
1400         return(NULL);
1401 }
1402
1403
1404 /* send message to peer
1405  */
1406 void EndpointAppPBX::cryptman_msg2peer(unsigned char *buf)
1407 {
1408         struct lcr_msg *message;
1409         unsigned char *p = buf;
1410         int len = 0;
1411         int l;
1412
1413         /* get len */
1414         while(p[0]) {
1415                 l = (p[1]<<8) + p[2];
1416                 len += l + 3;
1417                 p += l + 3;
1418         }
1419         if (len+1 > (int)sizeof(message->param.crypt.data)) {
1420                 PERROR("EPOINT(%d) message larger than allowed in param->crypt.data.\n", ea_endpoint->ep_serial);
1421                 return;
1422         }
1423         /* send message */
1424         message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_portlist->port_id, EPOINT_TO_PORT, MESSAGE_CRYPT);
1425         message->param.crypt.type = CR_MESSAGE_REQ;
1426         message->param.crypt.len = len+1;
1427         memcpy(message->param.crypt.data, buf, len+1);
1428         message_put(message);
1429
1430         if (options.deb & DEBUG_CRYPT) {
1431                 PDEBUG(DEBUG_CRYPT, "EPOINT(%d) sending message\n", ea_endpoint->ep_serial);
1432                 p = buf;
1433                 while(p[0]) {
1434                         l = (p[1]<<8) + p[2];
1435                         PDEBUG(DEBUG_CRYPT, "   inf %d (len = %d)\n", p[0], l);
1436                         len += l + 3;
1437                         p += l + 3;
1438                 }
1439         }
1440 }
1441
1442 /* send message to crypt engine
1443  */
1444 void EndpointAppPBX::cryptman_msg2crengine(int msg, unsigned char *buf, int len)
1445 {
1446         struct lcr_msg *message;
1447
1448         if (len > (int)sizeof(message->param.crypt.data)) {
1449                 PERROR("EPOINT(%d) message larger than allowed in param->crypt.data.\n", ea_endpoint->ep_serial);
1450                 return;
1451         }
1452         /* send message */
1453         message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_portlist->port_id, EPOINT_TO_PORT, MESSAGE_CRYPT);
1454         message->param.crypt.type = msg;
1455         message->param.crypt.len = len;
1456         if (len)
1457                 memcpy(message->param.crypt.data, buf, len);
1458         message_put(message);
1459
1460         if (options.deb & DEBUG_CRYPT) {
1461                 const char *msgtext = "<<UNKNOWN MESSAGE>>";
1462
1463                 if (msg>=0 && msg<cm_msg_num)
1464                         msgtext = cm_msg_name[msg];
1465                 PDEBUG(DEBUG_CRYPT, "EPOINT(%d) sending message '%s' (len = %d)\n", ea_endpoint->ep_serial, msgtext, len);
1466         }
1467 }
1468
1469 /* send message to user
1470  */
1471 void EndpointAppPBX::cryptman_msg2user(int msg, const char *text)
1472 {
1473         struct lcr_msg *message;
1474         /* send message */
1475         message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_join_id, EPOINT_TO_JOIN, MESSAGE_CRYPT);
1476         message->param.crypt.type = msg;
1477         if (!text)
1478                 text = "";
1479         SCPY(e_crypt_info, text);
1480         if (text[0]) {
1481                 UNCPY((char *)message->param.crypt.data, e_crypt_info, sizeof(message->param.crypt.data)-1);
1482                 message->param.crypt.len = strlen((char *)message->param.crypt.data)+1;
1483         }
1484         message_put(message);
1485
1486         if (options.deb & DEBUG_CRYPT) {
1487                 const char *msgtext = "<<UNKNOWN MESSAGE>>";
1488
1489                 if (msg>=0 && msg<cm_msg_num)
1490                         msgtext = cm_msg_name[msg];
1491                 PDEBUG(DEBUG_CRYPT, "EPOINT(%d) sending message '%s' (text = %s)\n", ea_endpoint->ep_serial, msgtext, text?text:"");
1492         }
1493 }
1494
1495 /* change state
1496  */
1497 void EndpointAppPBX::cryptman_state(int state)
1498 {
1499         PDEBUG(DEBUG_CRYPT, "Changing state from %s to %s\n", statename(e_crypt_state), statename(state));
1500         if (state != CM_ST_NULL && e_crypt_state == CM_ST_NULL)
1501                 schedule_timer(&e_crypt_handler, 0, 100000);
1502         e_crypt_state = state;
1503 }
1504
1505
1506 /* set timeout
1507  */
1508 void EndpointAppPBX::cryptman_timeout(int secs)
1509 {
1510         struct timeval current_time;
1511
1512         gettimeofday(&current_time, NULL);
1513         if (secs) {
1514                 e_crypt_timeout_sec = current_time.tv_sec+secs;
1515                 e_crypt_timeout_usec = current_time.tv_usec;
1516                 PDEBUG(DEBUG_CRYPT, "Changing timeout to %d seconds\n", secs);
1517         } else {
1518                 e_crypt_timeout_sec = 0;
1519                 e_crypt_timeout_usec = 0;
1520                 PDEBUG(DEBUG_CRYPT, "turning timeout off\n", secs);
1521         }
1522 }
1523
1524 /* encode a message to be sent via b-channel
1525  */
1526 int cryptman_encode_bch(unsigned char *data, int len, unsigned char *buf, int buf_len)
1527 {
1528         unsigned int crc;
1529         int overhead = 18;
1530
1531         len--; /* without null-termination */
1532         if (buf_len < len+overhead) {
1533                 PERROR("frame too long for buffer");
1534                 return(0);
1535         }
1536         PDEBUG(DEBUG_CRYPT, "encoding a block of %d bytes.\n", len);
1537
1538         /* write identification sequence to the header */
1539         UNCPY((char *)buf, "CRYPTMAN" ,8);
1540         buf += 8;
1541         /* length + checksumme */
1542         buf[0] = len >> 8;
1543         buf[1] = len & 0xff;
1544         crc = crc32(buf, 2);
1545         buf += 2;
1546         buf[0] = crc >> 24;
1547         buf[1] = crc >> 16;
1548         buf[2] = crc >> 8;
1549         buf[3] = crc;
1550         buf += 4;
1551         /* data + checksumme */
1552         memcpy(buf, data, len);
1553         crc = crc32(buf, len);
1554         buf += len;
1555         buf[0] = crc >> 24;
1556         buf[1] = crc >> 16;
1557         buf[2] = crc >> 8;
1558         buf[3] = crc;
1559         buf += 4;
1560         return(len + overhead);
1561 }
1562         
1563 /* decode a message from b-channel
1564  */
1565 void PmISDN::cryptman_listen_bch(unsigned char *p, int l)
1566 {
1567         int i;
1568         struct lcr_msg *message;
1569
1570         retry:
1571         if (!l)
1572                 return;
1573
1574         /* check for the keyword */
1575         if (p_m_crypt_listen_state == 0) {
1576                 while((*p++)!='C' && l)
1577                         l--;
1578                 if (!l)
1579                         return;
1580                 l--;
1581                 p_m_crypt_listen_state++;
1582                 if (!l)
1583                         return;
1584         }
1585         if (p_m_crypt_listen_state < 8) {
1586                 i = p_m_crypt_listen_state;
1587                 while(i < 8) {
1588                         l--;
1589                         if (*p++ != "CRYPTMAN"[i]) {
1590                                 p_m_crypt_listen_state = 0;
1591                                 goto retry;
1592                         }
1593                         p_m_crypt_listen_state++;
1594                         if (!l)
1595                                 break;
1596                         i++;
1597                 }
1598                 if (!l)
1599                         return;
1600         }
1601         /* high byte of length */
1602         if (p_m_crypt_listen_state == 8) {
1603                 p_m_crypt_listen_len = (*p++) << 8;
1604                 p_m_crypt_listen_state++;
1605                 if (!(--l))
1606                         return;
1607         }
1608         /* low byte of length */
1609         if (p_m_crypt_listen_state == 9) {
1610                 p_m_crypt_listen_len += *p++;
1611                 p_m_crypt_listen_state++;
1612                 if (!(--l))
1613                         return;
1614         }
1615         /* crc */
1616         if (p_m_crypt_listen_state == 10) {
1617                 p_m_crypt_listen_crc = (*p++) << 24;
1618                 p_m_crypt_listen_state++;
1619                 if (!(--l))
1620                         return;
1621         }
1622         if (p_m_crypt_listen_state == 11) {
1623                 p_m_crypt_listen_crc += (*p++) << 16;
1624                 p_m_crypt_listen_state++;
1625                 if (!(--l))
1626                         return;
1627         }
1628         if (p_m_crypt_listen_state == 12) {
1629                 p_m_crypt_listen_crc += (*p++) << 8;
1630                 p_m_crypt_listen_state++;
1631                 if (!(--l))
1632                         return;
1633         }
1634         if (p_m_crypt_listen_state == 13) {
1635                 unsigned char lencheck[2];
1636                 p_m_crypt_listen_crc += *p++;
1637                 /* check for CRC */
1638                 lencheck[0] = p_m_crypt_listen_len >> 8;
1639                 lencheck[1] = p_m_crypt_listen_len & 0xff;
1640                 if (crc32(lencheck, 2) != p_m_crypt_listen_crc) {
1641                         PDEBUG(DEBUG_CRYPT, "PmISDN(%s) received a block of %d bytes, but checksumme of length is incorrect (must %08x is %08x\n", p_name, p_m_crypt_listen_len, crc32(lencheck, 2), p_m_crypt_listen_crc);
1642                         p_m_crypt_listen_state = 0;
1643                         goto retry;
1644                 }
1645                 if (p_m_crypt_listen_len > (int)sizeof(p_m_crypt_listen_msg)) {
1646                         PDEBUG(DEBUG_CRYPT, "PmISDN(%s) received a block of %d bytes, but too big for buffer (%d bytes)\n", p_name, p_m_crypt_listen_len, sizeof(p_m_crypt_listen_msg));
1647                         p_m_crypt_listen_state = 0;
1648                         goto retry;
1649                 }
1650                 if (!p_m_crypt_listen_len) {
1651                         PDEBUG(DEBUG_CRYPT, "PmISDN(%s) received a block of 0 bytes\n", p_name);
1652                         p_m_crypt_listen_state = 0;
1653                         goto retry;
1654                 }
1655                 p_m_crypt_listen_state++;
1656                 if (!(--l))
1657                         return;
1658         }
1659         /* read message */
1660         while (p_m_crypt_listen_state>=14 && p_m_crypt_listen_state<(p_m_crypt_listen_len+14)) {
1661                 p_m_crypt_listen_msg[p_m_crypt_listen_state-14] = *p++;
1662                 p_m_crypt_listen_state++;
1663                 if (!(--l))
1664                         return;
1665         }
1666         /* crc */
1667         if (p_m_crypt_listen_state == 14+p_m_crypt_listen_len) {
1668                 p_m_crypt_listen_crc = (*p++) << 24;
1669                 p_m_crypt_listen_state++;
1670                 if (!(--l))
1671                         return;
1672         }
1673         if (p_m_crypt_listen_state == 15+p_m_crypt_listen_len) {
1674                 p_m_crypt_listen_crc += (*p++) << 16;
1675                 p_m_crypt_listen_state++;
1676                 if (!(--l))
1677                         return;
1678         }
1679         if (p_m_crypt_listen_state == 16+p_m_crypt_listen_len) {
1680                 p_m_crypt_listen_crc += (*p++) << 8;
1681                 p_m_crypt_listen_state++;
1682                 if (!(--l))
1683                         return;
1684         }
1685         if (p_m_crypt_listen_state == 17+p_m_crypt_listen_len) {
1686                 l--;
1687                 p_m_crypt_listen_crc += *p++;
1688                 /* check for CRC */
1689                 if (crc32(p_m_crypt_listen_msg, p_m_crypt_listen_len) != p_m_crypt_listen_crc) {
1690                         PDEBUG(DEBUG_CRYPT, "PmISDN(%s) received a block of %d bytes, but checksumme of data block is incorrect\n", p_name, p_m_crypt_listen_len);
1691                         p_m_crypt_listen_state = 0;
1692                         if (!l)
1693                                 return;
1694                         goto retry;
1695                 }
1696                 /* now send message */
1697                 p_m_crypt_listen_state = 0;
1698                 PDEBUG(DEBUG_CRYPT, "PmISDN(%s) received a block of %d bytes sending to crypt manager\n", p_name, p_m_crypt_listen_len);
1699                 if ((int)sizeof(message->param.crypt.data) < p_m_crypt_listen_len+1) /* null-terminated */ {
1700                         PDEBUG(DEBUG_CRYPT, "PmISDN(%s) received a block of %d bytes that is too large for message buffer\n", p_name, p_m_crypt_listen_len);
1701                         if (!l)
1702                                 return;
1703                         goto retry;
1704                 }
1705                 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CRYPT);
1706                 message->param.crypt.type = CR_MESSAGE_IND;
1707                 message->param.crypt.len = p_m_crypt_listen_len+1; /* null termination */
1708                 memcpy(message->param.crypt.data, p_m_crypt_listen_msg, p_m_crypt_listen_len);
1709                 message_put(message);
1710                 p_m_crypt_listen_state = 0;
1711                 if (!l)
1712                         return;
1713                 goto retry;
1714         }
1715 }
1716
1717
1718 /* encrypt call using share secret (keypad function)
1719  */
1720 void EndpointAppPBX::encrypt_shared(void)
1721 {
1722         struct lcr_msg *message;
1723         const char *errstr = "";
1724         class Port *port;
1725         int key_len;
1726         unsigned char *key;
1727         char *auth_pointer, *crypt_pointer, *key_pointer;
1728         int ret;
1729
1730         /* redisplay current crypt display */
1731         if (e_crypt != CRYPT_OFF) {
1732                 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) encryption in progress, so we request the current message.\n", ea_endpoint->ep_serial);
1733                 message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_join_id, EPOINT_TO_JOIN, MESSAGE_CRYPT);
1734                 message->param.crypt.type = CU_INFO_REQ;
1735                 message_put(message);
1736                 return;
1737         }
1738
1739         if (check_external(&errstr, &port)) {
1740                 reject:
1741                 message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_portlist->port_id, EPOINT_TO_PORT, MESSAGE_NOTIFY);
1742                 SCPY(message->param.notifyinfo.display, errstr);
1743                 message_put(message);
1744                 set_tone(ea_endpoint->ep_portlist, "crypt_off");
1745                 e_tone[0] = '\0';
1746                 return;
1747         }
1748
1749         /* check the key for the call */
1750         if (port->p_type==PORT_TYPE_DSS1_TE_OUT || port->p_type==PORT_TYPE_DSS1_NT_OUT)
1751                 ret = parse_secrets((char *)e_ext.number, (char *)port->p_dialinginfo.id, &auth_pointer, &crypt_pointer, &key_pointer);
1752         else {
1753                 if (!port->p_callerinfo.id[0]) {
1754                         PDEBUG(DEBUG_EPOINT, "EPOINT(%d) incoming remote call has no caller ID.\n", ea_endpoint->ep_serial);
1755                         errstr = "No Remote ID";
1756                         goto reject;
1757                 }
1758                 ret = parse_secrets((char *)e_ext.number, (char *)numberrize_callerinfo(port->p_callerinfo.id, port->p_callerinfo.ntype, options.national, options.international), &auth_pointer, &crypt_pointer, &key_pointer);
1759         }
1760         if (!ret) {
1761                 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) Key was not found.\n", ea_endpoint->ep_serial);
1762                 errstr = "No Key";
1763                 goto reject;
1764         }
1765         key = crypt_key((unsigned char *)key_pointer, &key_len);
1766         if (!key) {
1767                 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) Key invalid.\n", ea_endpoint->ep_serial);
1768                 errstr = "Invalid Key";
1769                 goto reject;
1770         }
1771         if (key_len > 128) {
1772                 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) Key too long.\n", ea_endpoint->ep_serial);
1773                 errstr = "Key Too Long";
1774                 goto reject;
1775         }
1776         if (!!strcasecmp(auth_pointer, "manual")) {
1777                 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) Wrong authentication method.\n", ea_endpoint->ep_serial);
1778                 errstr = "Wrong Auth Type";
1779                 goto reject;
1780         }
1781         if (!strcasecmp(crypt_pointer, "blowfish")) {
1782 //              type = CC_ACTBF_REQ;
1783                 if (key_len < 4) {
1784                         PDEBUG(DEBUG_EPOINT, "EPOINT(%d) Key too short.\n", ea_endpoint->ep_serial);
1785                         errstr = "Key Too Short";
1786                         goto reject;
1787                 }
1788                 if (key_len > 56) {
1789                         PDEBUG(DEBUG_EPOINT, "EPOINT(%d) Key too long.\n", ea_endpoint->ep_serial);
1790                         errstr = "Key Too Long";
1791                         goto reject;
1792                 }
1793         } else {
1794                 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) Wrong crypt method.\n", ea_endpoint->ep_serial);
1795                 errstr = "Wrong Crypt Type";
1796                 goto reject;
1797         }
1798
1799         PDEBUG(DEBUG_EPOINT, "EPOINT(%d) Key is ok, sending activation+key to cryptman.\n", ea_endpoint->ep_serial);
1800         /* setting display message and state */
1801 //      SPRINT(e_crypt_display, "Shared Key");
1802         e_crypt = CRYPT_SWAIT;
1803         /* sending activation */
1804         message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_join_id, EPOINT_TO_JOIN, MESSAGE_CRYPT);
1805         message->param.crypt.type = CU_ACTS_REQ;
1806         message->param.crypt.len = key_len;
1807         memcpy(message->param.crypt.data, key, key_len);
1808         message_put(message);
1809 }
1810
1811
1812 /* encrypt call using rsa authentication (keypad function)
1813  */
1814 void EndpointAppPBX::encrypt_keyex(void)
1815 {
1816         struct lcr_msg *message;
1817         const char *errstr = "";
1818         class Port *port;
1819
1820         /* redisplay current crypt display */
1821         if (e_crypt != CRYPT_OFF) {
1822                 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) encryption in progress, so we request the current message.\n", ea_endpoint->ep_serial);
1823                 message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_join_id, EPOINT_TO_JOIN, MESSAGE_CRYPT);
1824                 message->param.crypt.type = CU_INFO_REQ;
1825                 message_put(message);
1826                 return;
1827         }
1828
1829
1830         if (check_external(&errstr, &port)) {
1831                 message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_portlist->port_id, EPOINT_TO_PORT, MESSAGE_NOTIFY);
1832                 SCPY(message->param.notifyinfo.display, errstr);
1833                 message_put(message);
1834                 set_tone(ea_endpoint->ep_portlist, "crypt_off");
1835                 e_tone[0] = '\0';
1836                 return;
1837         }
1838
1839 #ifndef CRYPTO
1840         message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_portlist->port_id, EPOINT_TO_PORT, MESSAGE_NOTIFY);
1841         SCPY(message->param.notifyinfo.display, "Not Compiled");
1842         message_put(message);
1843         set_tone(ea_endpoint->ep_portlist, "crypt_off");
1844         e_tone[0] = '\0';
1845 #else
1846         PDEBUG(DEBUG_EPOINT, "EPOINT(%d) Sending key-exchange activation to cryptman.\n", ea_endpoint->ep_serial);
1847         /* setting display message and state */
1848 //      SPRINT(e_crypt_display, "Key-Exchange");
1849         message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_portlist->port_id, EPOINT_TO_PORT, MESSAGE_NOTIFY);
1850         SCPY(message->param.notifyinfo.display, "Key-Exchange");
1851         message_put(message);
1852         e_crypt = CRYPT_KWAIT;
1853         /* sending activation */
1854         message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_join_id, EPOINT_TO_JOIN, MESSAGE_CRYPT);
1855         message->param.crypt.type = CU_ACTK_REQ;
1856         message_put(message);
1857 #endif /* CRYPTO */
1858 }
1859
1860
1861 /* turn encryption off (keypad function)
1862  */
1863 void EndpointAppPBX::encrypt_off(void)
1864 {
1865         struct lcr_msg *message;
1866
1867         if (e_crypt!=CRYPT_ON && e_crypt!=CRYPT_OFF) {
1868                 message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_portlist->port_id, EPOINT_TO_PORT, MESSAGE_NOTIFY);
1869                 SCPY(message->param.notifyinfo.display, "Please Wait");
1870                 message_put(message);
1871                 return;
1872         }
1873         if (e_crypt == CRYPT_OFF) {
1874                 message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_portlist->port_id, EPOINT_TO_PORT, MESSAGE_NOTIFY);
1875                 SCPY(message->param.notifyinfo.display, "No Encryption");
1876                 message_put(message);
1877                 set_tone(ea_endpoint->ep_portlist, "crypt_off");
1878                 e_tone[0] = '\0';
1879                 return;
1880         }
1881
1882         PDEBUG(DEBUG_EPOINT, "EPOINT(%d) Sending deactivation to cryptman.\n", ea_endpoint->ep_serial);
1883         /* setting display message and state */
1884 //      SPRINT(e_crypt_display, "Deactivating");
1885         message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_portlist->port_id, EPOINT_TO_PORT, MESSAGE_NOTIFY);
1886         SCPY(message->param.notifyinfo.display, "Deactivating");
1887         message_put(message);
1888         e_crypt = CRYPT_RELEASE;
1889         /* sending activation */
1890         message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_join_id, EPOINT_TO_JOIN, MESSAGE_CRYPT);
1891         message->param.crypt.type = CU_DACT_REQ;
1892         message_put(message);
1893 }
1894
1895
1896 /* messages from manager to endpoint
1897  */
1898 void EndpointAppPBX::encrypt_result(int msg, char *text)
1899 {
1900         struct lcr_msg *message;
1901
1902         switch(msg) {
1903                 case CU_ACTK_CONF:
1904                 case CU_ACTS_CONF:
1905                 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) encryption now active.\n", ea_endpoint->ep_serial);
1906                 set_tone(ea_endpoint->ep_portlist, "crypt_on");
1907                 e_tone[0] = '\0';
1908                 e_crypt = CRYPT_ON;
1909                 display:
1910                 if (text) if (text[0]) {
1911                         SCPY(e_crypt_info, text);
1912                         message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_portlist->port_id, EPOINT_TO_PORT, MESSAGE_NOTIFY);
1913                         SCPY(message->param.notifyinfo.display, e_crypt_info);
1914                         message_put(message);
1915                 }
1916                 break;
1917
1918                 case CU_ERROR_IND:
1919                 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) encryption error. (%s)\n", ea_endpoint->ep_serial, text);
1920                 set_tone(ea_endpoint->ep_portlist, "crypt_off");
1921                 e_tone[0] = '\0';
1922                 e_crypt = CRYPT_OFF;
1923                 goto display;
1924                 break;
1925
1926                 case CU_DACT_CONF:
1927                 case CU_DACT_IND:
1928                 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) encryption now off. (%s)\n", ea_endpoint->ep_serial, text);
1929                 set_tone(ea_endpoint->ep_portlist, "crypt_off");
1930                 e_tone[0] = '\0';
1931                 e_crypt = CRYPT_OFF;
1932                 goto display;
1933                 break;
1934
1935                 case CU_INFO_CONF:
1936                 case CU_INFO_IND:
1937                 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) information. (%s)\n", ea_endpoint->ep_serial, text);
1938                 goto display;
1939                 break;
1940
1941                 default:
1942                 PERROR("EPOINT(%d) crypt manager sends us an invalid message. (type = %d)\n", ea_endpoint->ep_serial, msg);
1943         }
1944 }
1945
1946