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