Added new option to interface.conf: "nonotify" to disable notify messages.
[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         apppbx->ea_endpoint->ep_use--;
553         FREE(args, sizeof(struct auth_args));
554         amemuse--;
555         return(NULL);
556 }
557
558 void EndpointAppPBX::cryptman_keyengine(int job)
559 {
560         struct auth_args *arg;
561         pthread_t tid;
562
563         if (e_crypt_keyengine_busy) {
564                 e_crypt_keyengine_return = -1;
565                 PERROR("engine currently busy.\n");
566                 return;
567         }
568
569         arg = (struct auth_args *)MALLOC(sizeof(struct auth_args));
570         arg->apppbx = this;
571         arg->job = job;
572         e_crypt_keyengine_return = 0;
573         e_crypt_keyengine_busy = job;
574
575         ea_endpoint->ep_use++;
576         if ((pthread_create(&tid, NULL, keyengine_child, arg)<0)) {
577                 ea_endpoint->ep_use--;
578                 PERROR("failed to create keyengine-thread.\n");
579                 e_crypt_keyengine_return = -1;
580                 return;
581         }
582         amemuse++;
583
584         PDEBUG((DEBUG_EPOINT | DEBUG_CRYPT), "send_mail(%d): child process created for doing crypto stuff\n", ea_endpoint->ep_serial);
585
586 }
587
588
589 /* handler for authentication (called by apppbx's handler)
590  */
591 void EndpointAppPBX::cryptman_handler(void)
592 {
593         if (e_crypt_keyengine_busy) {
594                 if (e_crypt_keyengine_return < 0) {
595                         e_crypt_keyengine_busy = 0;
596                         cryptman_message(CK_ERROR_IND, NULL, 0);
597                 } else
598                 if (e_crypt_keyengine_return > 0) {
599                         switch(e_crypt_keyengine_busy) {
600                                 case CK_GENRSA_REQ:
601                                 e_crypt_keyengine_busy = 0;
602                                 cryptman_message(CK_GENRSA_CONF, NULL, 0);
603                                 break;
604                                 case CK_CPTRSA_REQ:
605                                 e_crypt_keyengine_busy = 0;
606                                 cryptman_message(CK_CPTRSA_CONF, NULL, 0);
607                                 break;
608                                 case CK_DECRSA_REQ:
609                                 e_crypt_keyengine_busy = 0;
610                                 cryptman_message(CK_DECRSA_CONF, NULL, 0);
611                                 break;
612                         }
613                 }
614         }
615
616         /* check for event, make next event */
617         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)) {
618                 e_crypt_timeout_sec = 0;
619                 e_crypt_timeout_usec = 0;
620                 cryptman_message(CT_TIMEOUT, NULL, 0);
621         }
622 }
623
624
625 /*
626  * process message to the crypt manager
627  */
628 /* remote peer sends ident request */
629 void EndpointAppPBX::cr_ident(int message, unsigned char *param, int len)
630 {
631         unsigned char buf[4], *p;
632         unsigned int bogomips = 0, ran;
633         int l;
634
635         l = CM_SIZEOFINF(CM_INFO_RANDOM);
636         if (l != 4) {
637                 PDEBUG(DEBUG_CRYPT, "EPOINT(%d) missing (or corrupt) random number, ignoring (len = %d)\n", ea_endpoint->ep_serial, l);
638                 return;
639         }
640         p = CM_GETINF(CM_INFO_RANDOM, buf);
641         ran = (p[0]<<24) + (p[1]<<16) + (p[2]<<8) + p[3];
642         l = CM_SIZEOFINF(CM_INFO_BOGOMIPS);
643         if (l != 4) {
644                 PDEBUG(DEBUG_CRYPT, "EPOINT(%d) missing (or corrupt) random bogomips, just comparing random (len = %d)\n", ea_endpoint->ep_serial, l);
645                 goto compare_random;
646         }
647         p = CM_GETINF(CM_INFO_BOGOMIPS, buf);
648         bogomips = (p[0]<<24) + (p[1]<<16) + (p[2]<<8) + p[3];
649         if (e_crypt_bogomips > bogomips) {
650                 PDEBUG(DEBUG_CRYPT, "EPOINT(%d) our cpu is faster, so we are master (%d > %d)\n", ea_endpoint->ep_serial, e_crypt_bogomips, bogomips);
651                 cr_master(message, NULL, 0);
652                 return;
653         }
654         if (e_crypt_bogomips < bogomips) {
655                 PDEBUG(DEBUG_CRYPT, "EPOINT(%d) our cpu is slower, so we are slave (%d < %d)\n", ea_endpoint->ep_serial, e_crypt_bogomips, bogomips);
656                 cr_slave(message, NULL, 0);
657                 return;
658         }
659         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);
660         compare_random:
661         /* bogomips are equal, so we compare */
662         if (e_crypt_random > ran) {
663                 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);
664                 cr_master(message, NULL, 0);
665                 return;
666         }
667         if (e_crypt_random < ran) {
668                 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);
669                 cr_slave(message, NULL, 0);
670                 return;
671         }
672         PDEBUG(DEBUG_CRYPT, "EPOINT(%d) random values are equal, so we are looped (%d == %d)\n", ea_endpoint->ep_serial, e_crypt_random, ran);
673         cr_looped(message, NULL, 0);
674 }
675
676 /* key-exchange activation by the user */
677 void EndpointAppPBX::cr_activate(int message, unsigned char *param, int len)
678 {
679         unsigned char buf[128] = "";
680         unsigned char msg;
681         unsigned char bogomips[4], ran[4];
682
683         /* activate listener */
684         cryptman_msg2crengine(CR_LISTEN_REQ, NULL, 0);
685         /* send ident message */
686         msg = CMSG_IDENT;
687         CM_ADDINF(CM_INFO_MESSAGE, 1, &msg);
688         /* random number element */
689         srandom(now_tv.tv_sec ^ now_tv.tv_usec ^ random());
690         e_crypt_random = random();
691         ran[0] = e_crypt_random >> 24;
692         ran[1] = e_crypt_random >> 16;
693         ran[2] = e_crypt_random >> 8;
694         ran[3] = e_crypt_random;
695         CM_ADDINF(CM_INFO_RANDOM, 4, ran);
696         /* cpu speed element */
697         e_crypt_bogomips = get_bogomips();
698         if (e_crypt_bogomips > 0) {
699                 bogomips[0] = e_crypt_bogomips >> 24;
700                 bogomips[1] = e_crypt_bogomips >> 16;
701                 bogomips[2] = e_crypt_bogomips >> 8;
702                 bogomips[3] = e_crypt_bogomips;
703                 CM_ADDINF(CM_INFO_BOGOMIPS, 4, bogomips);
704         }
705         /* send ident message */
706         cryptman_msg2peer(buf);
707         /* change state */
708         cryptman_state(CM_ST_IDENT);
709         /* set timeout */
710         cryptman_timeout(CM_TO_IDENT);
711 }
712
713 /* deactivation by the user */
714 void EndpointAppPBX::cr_deactivate(int message, unsigned char *param, int len)
715 {
716         unsigned char buf[128] = "";
717         unsigned char msg;
718
719         /* deactivate listener (if not already) */
720         cryptman_msg2crengine(CR_UNLISTEN_REQ, NULL, 0);
721         /* message */
722         msg = CMSG_ABORT;
723         CM_ADDINF(CM_INFO_MESSAGE, 1, &msg);
724         cryptman_msg2peer(buf);
725         /* deactivate encryption */
726         cryptman_msg2crengine(CC_DACT_REQ, NULL, 0);
727         /* change state */
728         cryptman_state(CM_ST_NULL);
729         /* send message to user */
730         cryptman_msg2user(CU_DACT_CONF, "Deactivated");
731 }
732
733 /* remote peer tells us to be master */
734 void EndpointAppPBX::cr_master(int message, unsigned char *param, int len)
735 {
736         unsigned char buf[128] = "";
737         unsigned char msg;
738
739         /* change to master state */
740         cryptman_state(CM_ST_KEYGEN);
741         if (message == CP_IDENT) {
742                 /* send you-are-slave-message */
743                 msg = CMSG_SLAVE;
744                 CM_ADDINF(CM_INFO_MESSAGE, 1, &msg);
745                 cryptman_msg2peer(buf);
746         }
747         /* start generation of key */
748         cryptman_keyengine(CK_GENRSA_REQ);
749         /* disable timeout */
750         cryptman_timeout(0);
751         /* send message to user */
752         cryptman_msg2user(CU_INFO_IND, "Master");
753 }
754
755 /* remote peer tells us to be slave */
756 void EndpointAppPBX::cr_slave(int message, unsigned char *param, int len)
757 {
758         unsigned char buf[128] = "";
759         unsigned char msg;
760
761         /* change to slave state */
762         cryptman_state(CM_ST_KEYWAIT);
763         if (message == CP_IDENT) {
764                 /* send you-are-slave-message */
765                 msg = CMSG_MASTER;
766                 /* message */
767                 CM_ADDINF(CM_INFO_MESSAGE, 1, &msg);
768                 cryptman_msg2peer(buf);
769         }
770         /* set timeout */
771         cryptman_timeout(CM_TO_PUBKEY);
772         /* send message to user */
773         cryptman_msg2user(CU_INFO_IND, "Slave");
774 }
775
776 /* remote peer tells us about loop */
777 void EndpointAppPBX::cr_looped(int message, unsigned char *param, int len)
778 {
779         unsigned char buf[128] = "";
780         unsigned char msg;
781
782         /* change to idle state */
783         cryptman_state(CM_ST_NULL);
784         /* deactivate listener */
785         cryptman_msg2crengine(CR_UNLISTEN_REQ, NULL, 0);
786         if (message == CP_IDENT) {
787                 /* send looped */
788                 msg = CMSG_LOOPED;
789                 /* message */
790                 CM_ADDINF(CM_INFO_MESSAGE, 1, &msg);
791                 cryptman_msg2peer(buf);
792         }
793         /* disable timeout */
794         cryptman_timeout(0);
795         /* send message to user */
796         cryptman_msg2user(CU_ERROR_IND, "Loop Detected");
797 }
798
799 /* abort */
800 void EndpointAppPBX::cr_abort(int message, unsigned char *param, int len)
801 {
802         /* if already encrypting */
803         if (e_crypt_state==CM_ST_WAIT_CRYPT
804          || e_crypt_state==CM_ST_SWAIT
805          || e_crypt_state==CM_ST_ACTIVE) {
806                 /* deactivate blowfish */
807                 cryptman_msg2crengine(CC_DACT_REQ, NULL, 0);
808         }
809         /* change to idle state */
810         cryptman_state(CM_ST_NULL);
811         /* deactivate listener */
812         cryptman_msg2crengine(CR_UNLISTEN_REQ, NULL, 0);
813         /* disable timeout */
814         cryptman_timeout(0);
815         /* send message to user */
816         if (message == CT_TIMEOUT)
817                 cryptman_msg2user(CU_ERROR_IND, "Timeout");
818         else if (message == CP_ABORT)
819                 cryptman_msg2user(CU_ERROR_IND, "Remote Abort");
820         else
821                 cryptman_msg2user(CU_DACT_IND, NULL);
822 }
823
824 /* abort but wait for engine to release*/
825 void EndpointAppPBX::cr_abort_engine(int message, unsigned char *param, int len)
826 {
827         /* change to release state */
828         cryptman_state(CM_ST_RELEASE);
829         /* deactivate listener */
830         cryptman_msg2crengine(CR_UNLISTEN_REQ, NULL, 0);
831         /* disable timeout */
832         cryptman_timeout(0);
833         /* send message to user */
834         if (message == CT_TIMEOUT)
835                 cryptman_msg2user(CU_ERROR_IND, "Timeout");
836         else if (message == CP_ABORT)
837                 cryptman_msg2user(CU_ERROR_IND, "Remote Abort");
838         else
839                 cryptman_msg2user(CU_DACT_IND, NULL);
840 }
841
842 /* abort and disable crypt engine */
843 void EndpointAppPBX::cr_abort_wait(int message, unsigned char *param, int len)
844 {
845         /* change to idle state */
846         cryptman_state(CM_ST_NULL);
847         /* deactivate listener (if not already) */
848         cryptman_msg2crengine(CR_UNLISTEN_REQ, NULL, 0);
849         /* deactivate blowfish */
850         cryptman_msg2crengine(CC_DACT_REQ, NULL, 0);
851         /* disable timeout */
852         cryptman_timeout(0);
853         /* send message to user */
854         if (message == CT_TIMEOUT)
855                 cryptman_msg2user(CU_ERROR_IND, "Timeout");
856         else if (message == CP_ABORT)
857                 cryptman_msg2user(CU_ERROR_IND, "Remote Abort");
858         else
859                 cryptman_msg2user(CU_DACT_IND, NULL);
860 }
861
862 /* key engine tells us that the rsa is ready */
863 void EndpointAppPBX::cr_genrsa(int message, unsigned char *param, int len)
864 {
865         unsigned char buf[1024] = "";
866         unsigned char msg;
867
868         /* change to wait for crypted session key state */
869         cryptman_state(CM_ST_CSWAIT);
870         /* message */
871         msg = CMSG_PUBKEY;
872         CM_ADDINF(CM_INFO_MESSAGE, 1, &msg);
873         CM_ADDINF(CM_INFO_PUBKEY, e_crypt_rsa_n_len, &e_crypt_rsa_n);
874         CM_ADDINF(CM_INFO_PUBEXPONENT, e_crypt_rsa_e_len, &e_crypt_rsa_e);
875         cryptman_msg2peer(buf);
876         /* set timeout */
877         cryptman_timeout(CM_TO_CSKEY);
878 }
879
880 /* our engine has a key error */
881 void EndpointAppPBX::cr_keyerror(int message, unsigned char *param, int len)
882 {
883         unsigned char buf[128] = "";
884         unsigned char msg;
885
886         /* change to idle state */
887         cryptman_state(CM_ST_NULL);
888         /* deactivate listener */
889         cryptman_msg2crengine(CR_UNLISTEN_REQ, NULL, 0);
890         /* message */
891         msg = CMSG_ABORT;
892         CM_ADDINF(CM_INFO_MESSAGE, 1, &msg);
893         cryptman_msg2peer(buf);
894         /* send message to user */
895         cryptman_msg2user(CU_ERROR_IND, "Local Key Error");
896 }
897
898 /* remote sends us the rsa public key */
899 void EndpointAppPBX::cr_pubkey(int message, unsigned char *param, int len)
900 {
901         unsigned char buf[128] = "";
902         unsigned char msg = CMSG_ABORT;
903         int l;
904
905         l = CM_SIZEOFINF(CM_INFO_PUBKEY);
906         if (l<1 || l>(int)sizeof(e_crypt_rsa_n)) {
907                 size_error:
908                 /* change to idle state */
909                 cryptman_state(CM_ST_NULL);
910                 /* deactivate listener */
911                 cryptman_msg2crengine(CR_UNLISTEN_REQ, NULL, 0);
912                 /* message */
913                 CM_ADDINF(CM_INFO_MESSAGE, 1, &msg);
914                 cryptman_msg2peer(buf);
915                 /* send message to user */
916                 cryptman_msg2user(CU_ERROR_IND, "Remote Key Error");
917                 return;
918         }
919         CM_GETINF(CM_INFO_PUBKEY, e_crypt_rsa_n);
920         e_crypt_rsa_n_len = l;
921         l = CM_SIZEOFINF(CM_INFO_PUBEXPONENT);
922         if (l<1 || l>(int)sizeof(e_crypt_rsa_e))
923                 goto size_error;
924         CM_GETINF(CM_INFO_PUBEXPONENT, e_crypt_rsa_e);
925         e_crypt_rsa_e_len = l;
926         /* change to generating encrypted sessnion key state */
927         cryptman_state(CM_ST_CSKEY);
928         /* start generation of crypted session key */
929         cryptman_keyengine(CK_CPTRSA_REQ);
930         /* disable timeout */
931         cryptman_timeout(0);
932 }
933
934 /* key engine tells us that the crypted session key is ready */
935 void EndpointAppPBX::cr_cptrsa(int message, unsigned char *param, int len)
936 {
937         unsigned char buf[1024] = "";
938         unsigned char msg = CMSG_CSKEY;
939
940         /* change to wait for crypt engine state */
941         cryptman_state(CM_ST_WAIT_DELAY);
942         /* message */
943         CM_ADDINF(CM_INFO_MESSAGE, 1, &msg);
944         CM_ADDINF(CM_INFO_CSKEY, e_crypt_ckey_len, &e_crypt_ckey);
945         cryptman_msg2peer(buf);
946         /* deactivate listener */
947         cryptman_msg2crengine(CR_UNLISTEN_REQ, NULL, 0);
948         /* timeout 1 sec */
949         cryptman_timeout(1);
950 }
951
952 /* now we waited for the remote to receive and decrypt the session key */
953 void EndpointAppPBX::cr_waitdelay(int message, unsigned char *param, int len)
954 {
955         /* change to wait for crypt engine state */
956         cryptman_state(CM_ST_WAIT_CRYPT);
957         /* disable timeout */
958         cryptman_timeout(0);
959         /* send message to crypt engine */
960         cryptman_msg2crengine(CC_ACTBF_REQ, e_crypt_key, e_crypt_key_len);
961 }
962
963 /* remote sends us the crypted session key */
964 void EndpointAppPBX::cr_cskey(int message, unsigned char *param, int len)
965 {
966         unsigned char buf[128] = "";
967         unsigned char msg = CMSG_ABORT;
968         int l;
969
970         /* disable timeout */
971         cryptman_timeout(0);
972         l = CM_SIZEOFINF(CM_INFO_CSKEY);
973         if (l<1 || l>(int)sizeof(e_crypt_ckey)) {
974                 /* change to idle state */
975                 cryptman_state(CM_ST_NULL);
976                 /* deactivate listener */
977                 cryptman_msg2crengine(CR_UNLISTEN_REQ, NULL, 0);
978                 /* message */
979                 CM_ADDINF(CM_INFO_MESSAGE, 1, &msg);
980                 cryptman_msg2peer(buf);
981                 /* send message to user */
982                 cryptman_msg2user(CU_ERROR_IND, "Remote Key Error");
983                 return;
984         }
985         CM_GETINF(CM_INFO_CSKEY, e_crypt_ckey);
986         e_crypt_ckey_len = l;
987         /* change to generating decrypted session key state */
988         cryptman_state(CM_ST_SESSION);
989         /* start generation of decrypted session key */
990         cryptman_keyengine(CK_DECRSA_REQ);
991 }
992
993 /* key engine tells us that the decrypted session key is ready */
994 void EndpointAppPBX::cr_decrsa(int message, unsigned char *param, int len)
995 {
996         /* change to wait for crypt engine state */
997         cryptman_state(CM_ST_WAIT_CRYPT);
998         /* deactivate listener */
999         cryptman_msg2crengine(CR_UNLISTEN_REQ, NULL, 0);
1000         /* send message to crypt engine */
1001         cryptman_msg2crengine(CC_ACTBF_REQ, e_crypt_key, e_crypt_key_len);
1002 }
1003
1004 /* blowfish now active */
1005 void EndpointAppPBX::cr_bfactive(int message, unsigned char *param, int len)
1006 {
1007         char text[64];
1008
1009         /* change to active state */
1010         cryptman_state(CM_ST_ACTIVE);
1011         /* send message to user */
1012         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]);
1013         cryptman_msg2user(CU_ACTK_CONF, text);
1014 }
1015
1016 /* our crypt engine sends an error */
1017 void EndpointAppPBX::cr_crypterror(int message, unsigned char *param, int len)
1018 {
1019         unsigned char buf[128] = "";
1020         unsigned char msg = CMSG_ABORT;
1021
1022         /* change to idle state */
1023         cryptman_state(CM_ST_NULL);
1024         /* deactivate listener */
1025         cryptman_msg2crengine(CR_UNLISTEN_REQ, NULL, 0);
1026         /* message */
1027         CM_ADDINF(CM_INFO_MESSAGE, 1, &msg);
1028         cryptman_msg2peer(buf);
1029         /* send message to user */
1030         cryptman_msg2user(CU_ERROR_IND, "Blowfish Error");
1031 }
1032
1033 /* engine is done, now we are done with release */
1034 void EndpointAppPBX::cr_release(int message, unsigned char *param, int len)
1035 {
1036         /* change to idle state */
1037         cryptman_state(CM_ST_NULL);
1038 }
1039
1040 /* activate using shared key */
1041 void EndpointAppPBX::cr_sactivate(int message, unsigned char *param, int len)
1042 {
1043         /* change to 'wait for crypt engine' state */
1044         cryptman_state(CM_ST_SWAIT);
1045         /* disable timeout */
1046         cryptman_timeout(0);
1047         /* send key to crypt engine */
1048         cryptman_msg2crengine(CC_ACTBF_REQ, param, len);
1049 }
1050
1051 /* share key deactivation by the user */
1052 void EndpointAppPBX::cr_sdeactivate(int message, unsigned char *param, int len)
1053 {
1054         /* deactivate encryption */
1055         cryptman_msg2crengine(CC_DACT_REQ, NULL, 0);
1056         /* change state */
1057         cryptman_state(CM_ST_NULL);
1058         /* send message to user */
1059         cryptman_msg2user(CU_DACT_CONF, NULL);
1060 }
1061
1062 /* shared key abort */
1063 void EndpointAppPBX::cr_sabort(int message, unsigned char *param, int len)
1064 {
1065         /* change to idle state */
1066         cryptman_state(CM_ST_NULL);
1067         /* send message to user */
1068         cryptman_msg2user(CU_DACT_IND, "Deactivated");
1069 }
1070
1071 /* shared key: our crypt engine sends an error */
1072 void EndpointAppPBX::cr_scrypterror(int message, unsigned char *param, int len)
1073 {
1074         /* change to idle state */
1075         cryptman_state(CM_ST_NULL);
1076         /* send message to user */
1077         cryptman_msg2user(CU_ERROR_IND, "Blowfish Error");
1078 }
1079
1080 /* blowfish now active */
1081 void EndpointAppPBX::cr_sbfactive(int message, unsigned char *param, int len)
1082 {
1083         char text[64];
1084
1085         /* change to active state */
1086         cryptman_state(CM_ST_SACTIVE);
1087         /* send message to user */
1088         SPRINT(text, "Call Secure");
1089         cryptman_msg2user(CU_ACTS_CONF, text);
1090 }
1091
1092 /* user requests info */
1093 void EndpointAppPBX::cr_info(int message, unsigned char *param, int len)
1094 {
1095         /* send message to user */
1096         cryptman_msg2user(CU_INFO_CONF, e_crypt_info);
1097 }
1098
1099
1100 CM_MSG_NAMES
1101
1102 void EndpointAppPBX::cryptman_message(int message, unsigned char *param, int len)
1103 {
1104         const char *msgtext = "<<UNKNOWN MESSAGE>>";
1105
1106         if (message>=0 && message<cm_msg_num)
1107                 msgtext = cm_msg_name[message];
1108
1109         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);
1110
1111         /* all states */
1112         if (message == CU_INFO_REQ)
1113                 { cr_info(message, param, len); return; }
1114
1115         switch(e_crypt_state) {
1116                 /* in idle state */
1117                 case CM_ST_NULL:
1118                 if (message == CU_ACTK_REQ) /* request key-exchange encryption */
1119                         { cr_activate(message, param, len); return; }
1120                 if (message == CU_ACTS_REQ) /* request shared encryption */
1121                         { cr_sactivate(message, param, len); return; }
1122                 break;
1123
1124                 /* identifying state */
1125                 case CM_ST_IDENT:
1126                 if (message == CP_IDENT) /* request encryption */
1127                         { cr_ident(message, param, len); return; }
1128                 if (message == CP_SLAVE) /* we are slave */
1129                         { cr_slave(message, param, len); return; }
1130                 if (message == CP_MASTER) /* we are master */
1131                         { cr_master(message, param, len); return; }
1132                 if (message == CP_LOOPED) /* we are looped */
1133                         { cr_looped(message, param, len); return; }
1134                 if (message == CI_DISCONNECT_IND /* request aborting */
1135                  || message == CT_TIMEOUT /* timeout */
1136                  || message == CP_ABORT) /* request aborting */
1137                         { cr_abort(message, param, len); return; }
1138                 break;
1139
1140                 /* generating public key state */
1141                 case CM_ST_KEYGEN:
1142                 if (message == CK_GENRSA_CONF) /* public key is done */
1143                         { cr_genrsa(message, param, len); return; }
1144                 if (message == CK_ERROR_IND) /* key failed */
1145                         { cr_keyerror(message, param, len); return; }
1146                 if (message == CI_DISCONNECT_IND /* request aborting */
1147                  || message == CP_ABORT) /* request aborting */
1148                         { cr_abort_engine(message, param, len); return; }
1149                 break;
1150
1151                 /* waiting for public key state */
1152                 case CM_ST_KEYWAIT:
1153                 if (message == CP_PUBKEY) /* getting public key from remote */
1154                         { cr_pubkey(message, param, len); return; }
1155                 if (message == CI_DISCONNECT_IND /* request aborting */
1156                  || message == CT_TIMEOUT /* timeout */
1157                  || message == CP_ABORT) /* request aborting */
1158                         { cr_abort(message, param, len); return; }
1159                 break;
1160
1161                 /* generating crypted session key state */
1162                 case CM_ST_CSKEY:
1163                 if (message == CK_CPTRSA_CONF) /* crypted session key is done */
1164                         { cr_cptrsa(message, param, len); return; }
1165                 if (message == CK_ERROR_IND) /* key failed */
1166                         { cr_keyerror(message, param, len); return; }
1167                 if (message == CI_DISCONNECT_IND /* request aborting */
1168                  || message == CP_ABORT) /* request aborting */
1169                         { cr_abort_engine(message, param, len); return; }
1170                 break;
1171
1172                 /* waiting for crypted session key state */
1173                 case CM_ST_CSWAIT:
1174                 if (message == CP_CSKEY) /* getting crypted session key from remote */
1175                         { cr_cskey(message, param, len); return; }
1176                 if (message == CI_DISCONNECT_IND /* request aborting */
1177                  || message == CT_TIMEOUT /* timeout */
1178                  || message == CP_ABORT) /* request aborting */
1179                         { cr_abort(message, param, len); return; }
1180                 break;
1181
1182                 /* generating decrypted session key state */
1183                 case CM_ST_SESSION:
1184                 if (message == CK_DECRSA_CONF) /* decrypted is done */
1185                         { cr_decrsa(message, param, len); return; }
1186                 if (message == CK_ERROR_IND) /* key failed */
1187                         { cr_keyerror(message, param, len); return; }
1188                 if (message == CI_DISCONNECT_IND /* request aborting */
1189                  || message == CP_ABORT) /* request aborting */
1190                         { cr_abort_engine(message, param, len); return; }
1191                 break;
1192
1193                 /* wait encryption on state */
1194                 case CM_ST_WAIT_DELAY:
1195                 if (message == CT_TIMEOUT) /* timeout of delay */
1196                         { cr_waitdelay(message, param, len); return; }
1197                 if (message == CC_ERROR_IND) /* encrpytion error */
1198                         { cr_crypterror(message, param, len); return; }
1199                 if (message == CI_DISCONNECT_IND /* request aborting */
1200                  || message == CP_ABORT) /* request aborting */
1201                         { cr_abort_wait(message, param, len); return; }
1202                 break;
1203
1204                 /* wait encryption on state */
1205                 case CM_ST_WAIT_CRYPT:
1206                 if (message == CC_ACTBF_CONF) /* encrpytion active */
1207                         { cr_bfactive(message, param, len); return; }
1208                 if (message == CC_ERROR_IND) /* encrpytion error */
1209                         { cr_crypterror(message, param, len); return; }
1210                 if (message == CI_DISCONNECT_IND /* request aborting */
1211                  || message == CP_ABORT) /* request aborting */
1212                         { cr_abort_wait(message, param, len); return; }
1213                 break;
1214
1215                 /* active state */
1216                 case CM_ST_ACTIVE:
1217                 if (message == CU_DACT_REQ) /* deactivating encryption */
1218                         { cr_deactivate(message, param, len); return; }
1219                 if (message == CI_DISCONNECT_IND /* request aborting */
1220                  || message == CP_ABORT) /* request aborting */
1221                         { cr_abort(message, param, len); return; }
1222                 break;
1223
1224
1225                 /* engine done after abort state */
1226                 case CM_ST_RELEASE:
1227                 if (message == CK_GENRSA_CONF /* engine done */
1228                  || message == CK_CPTRSA_CONF /* engine done */
1229                  || message == CK_DECRSA_CONF /* engine done */
1230                  || message == CK_ERROR_IND) /* engine error */
1231                         { cr_release(message, param, len); return; }
1232                 break;
1233
1234                 /* shared active state */
1235                 case CM_ST_SACTIVE:
1236                 if (message == CU_DACT_REQ) /* deactivating encryption */
1237                         { cr_sdeactivate(message, param, len); return; }
1238                 if (message == CI_DISCONNECT_IND) /* request aborting */
1239                         { cr_sabort(message, param, len); return; }
1240                 break;
1241
1242                 /* wait shared encryption on state */
1243                 case CM_ST_SWAIT:
1244                 if (message == CC_ACTBF_CONF) /* encrpytion active */
1245                         { cr_sbfactive(message, param, len); return; }
1246                 if (message == CC_ERROR_IND) /* encrpytion error */
1247                         { cr_scrypterror(message, param, len); return; }
1248                 if (message == CI_DISCONNECT_IND) /* request aborting */
1249                         { cr_sabort(message, param, len); return; }
1250                 break;
1251
1252         }
1253
1254         PDEBUG(DEBUG_CRYPT, "message not handled in state %d\n", e_crypt_state);
1255 }
1256
1257
1258 /*
1259  * analyze the message element within the received message from peer and call 'cryptman_message'
1260  */
1261 void EndpointAppPBX::cryptman_msg2man(unsigned char *param, int len)
1262 {
1263         unsigned char *p;
1264         unsigned char msg;
1265         int i, l;
1266
1267         /* check if frame is correct */
1268         PDEBUG(DEBUG_CRYPT, "EPOINT(%d) message from peer to crypt_manager.\n", ea_endpoint->ep_serial);
1269         if (len == 0) {
1270                 PDEBUG(DEBUG_CRYPT, "ignoring message with 0-length.\n");
1271                 return;
1272         }
1273         i = 0;
1274         p = param;
1275         while(*p) {
1276                 if (i == len) {
1277                         PDEBUG(DEBUG_CRYPT, "end of message without 0-termination.\n");
1278                         return;
1279                 }
1280                 if (i+3 > len) {
1281                         PDEBUG(DEBUG_CRYPT, "message with element size, outside the frame length.\n");
1282                         return;
1283                 }
1284                 l = (p[1]<<8) + p[2];
1285 //              PDEBUG(DEBUG_CRYPT, "   inf %d (len = %d)\n", *p, l);
1286                 if (i+3+l > len) {
1287                         PDEBUG(DEBUG_CRYPT, "message with element data, outside the frame length.\n");
1288                         return;
1289                 }
1290                 i += l + 3;
1291                 p += l + 3;
1292         }
1293         if (i+1 != len) {
1294                 PDEBUG(DEBUG_CRYPT, "warning: received null-element before end of frame.\n");
1295         }
1296
1297         l = CM_SIZEOFINF(CM_INFO_MESSAGE);
1298         if (l != 1) {
1299                 PDEBUG(DEBUG_CRYPT, "received message without (valid) message element (len = %d)\n", len);
1300                 return;
1301         }
1302         CM_GETINF(CM_INFO_MESSAGE, &msg);
1303         switch (msg) {
1304                 case CMSG_IDENT:
1305                 cryptman_message(CP_IDENT, param, len);
1306                 break;
1307                 case CMSG_SLAVE:
1308                 cryptman_message(CP_SLAVE, param, len);
1309                 break;
1310                 case CMSG_MASTER:
1311                 cryptman_message(CP_MASTER, param, len);
1312                 break;
1313                 case CMSG_PUBKEY:
1314                 cryptman_message(CP_PUBKEY, param, len);
1315                 break;
1316                 case CMSG_CSKEY:
1317                 cryptman_message(CP_CSKEY, param, len);
1318                 break;
1319                 case CMSG_ABORT:
1320                 cryptman_message(CP_ABORT, param, len);
1321                 break;
1322                 default:
1323                 PDEBUG(DEBUG_CRYPT, "received unknown message element %d\n", msg);
1324         }
1325 }
1326
1327 /* add information element to buffer
1328  */
1329 void EndpointAppPBX::cryptman_addinf(unsigned char *buf, int buf_size, int element, int len, void *data)
1330 {
1331         int l;
1332
1333         /* skip what we already have in the buffer */
1334         while (buf[0]) {
1335                 l = (buf[1]<<8) + buf[2];
1336                 if (l >= buf_size-3) {
1337                         PERROR("EPOINT(%d) buffer overflow while adding information to peer message.\n", ea_endpoint->ep_serial);
1338                         return;
1339                 }
1340                 buf_size -= l + 3;
1341                 buf += l + 3;
1342         }
1343         /* check if we have not enough space to add element including id, len, data, and the null-termination */
1344         if (len+4 > buf_size) {
1345                 PERROR("EPOINT(%d) cannot add element to message, because buffer would overflow.\n", ea_endpoint->ep_serial);
1346                 return;
1347         }
1348         buf[0] = element;
1349         buf[1] = len >> 8;
1350         buf[2] = len;
1351         memcpy(buf+3, data, len);
1352 }
1353
1354
1355 /* get size of element in buffer
1356  */
1357 int EndpointAppPBX::cryptman_sizeofinf(unsigned char *buf, int element)
1358 {
1359         int l;
1360
1361         /* skip what we already have in the buffer */
1362         while (buf[0]) {
1363                 l = (buf[1]<<8) + buf[2];
1364                 if (buf[0] == element)
1365                         return(l);
1366                 buf += l + 3;
1367         }
1368         return(-1);
1369 }
1370
1371
1372 /* get information element from buffer
1373  */
1374 unsigned char *EndpointAppPBX::cryptman_getinf(unsigned char *buf, int element, unsigned char *to)
1375 {
1376         int l;
1377
1378         /* skip what we already have in the buffer */
1379         while (buf[0]) {
1380                 l = (buf[1]<<8) + buf[2];
1381                 if (buf[0] == element) {
1382                         memcpy(to, buf+3, l);
1383                         return(to);
1384                 }
1385                 buf += l + 3;
1386         }
1387         return(NULL);
1388 }
1389
1390
1391 /* send message to peer
1392  */
1393 void EndpointAppPBX::cryptman_msg2peer(unsigned char *buf)
1394 {
1395         struct lcr_msg *message;
1396         unsigned char *p = buf;
1397         int len = 0;
1398         int l;
1399
1400         /* get len */
1401         while(p[0]) {
1402                 l = (p[1]<<8) + p[2];
1403                 len += l + 3;
1404                 p += l + 3;
1405         }
1406         if (len+1 > (int)sizeof(message->param.crypt.data)) {
1407                 PERROR("EPOINT(%d) message larger than allowed in param->crypt.data.\n", ea_endpoint->ep_serial);
1408                 return;
1409         }
1410         /* send message */
1411         message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_portlist->port_id, EPOINT_TO_PORT, MESSAGE_CRYPT);
1412         message->param.crypt.type = CR_MESSAGE_REQ;
1413         message->param.crypt.len = len+1;
1414         memcpy(message->param.crypt.data, buf, len+1);
1415         message_put(message);
1416
1417         if (options.deb & DEBUG_CRYPT) {
1418                 PDEBUG(DEBUG_CRYPT, "EPOINT(%d) sending message\n", ea_endpoint->ep_serial);
1419                 p = buf;
1420                 while(p[0]) {
1421                         l = (p[1]<<8) + p[2];
1422                         PDEBUG(DEBUG_CRYPT, "   inf %d (len = %d)\n", p[0], l);
1423                         len += l + 3;
1424                         p += l + 3;
1425                 }
1426         }
1427 }
1428
1429 /* send message to crypt engine
1430  */
1431 void EndpointAppPBX::cryptman_msg2crengine(int msg, unsigned char *buf, int len)
1432 {
1433         struct lcr_msg *message;
1434
1435         if (len > (int)sizeof(message->param.crypt.data)) {
1436                 PERROR("EPOINT(%d) message larger than allowed in param->crypt.data.\n", ea_endpoint->ep_serial);
1437                 return;
1438         }
1439         /* send message */
1440         message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_portlist->port_id, EPOINT_TO_PORT, MESSAGE_CRYPT);
1441         message->param.crypt.type = msg;
1442         message->param.crypt.len = len;
1443         if (len)
1444                 memcpy(message->param.crypt.data, buf, len);
1445         message_put(message);
1446
1447         if (options.deb & DEBUG_CRYPT) {
1448                 const char *msgtext = "<<UNKNOWN MESSAGE>>";
1449
1450                 if (msg>=0 && msg<cm_msg_num)
1451                         msgtext = cm_msg_name[msg];
1452                 PDEBUG(DEBUG_CRYPT, "EPOINT(%d) sending message '%s' (len = %d)\n", ea_endpoint->ep_serial, msgtext, len);
1453         }
1454 }
1455
1456 /* send message to user
1457  */
1458 void EndpointAppPBX::cryptman_msg2user(int msg, const char *text)
1459 {
1460         struct lcr_msg *message;
1461         /* send message */
1462         message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_join_id, EPOINT_TO_JOIN, MESSAGE_CRYPT);
1463         message->param.crypt.type = msg;
1464         if (!text)
1465                 text = "";
1466         SCPY(e_crypt_info, text);
1467         if (text[0]) {
1468                 UNCPY((char *)message->param.crypt.data, e_crypt_info, sizeof(message->param.crypt.data)-1);
1469                 message->param.crypt.len = strlen((char *)message->param.crypt.data)+1;
1470         }
1471         message_put(message);
1472
1473         if (options.deb & DEBUG_CRYPT) {
1474                 const char *msgtext = "<<UNKNOWN MESSAGE>>";
1475
1476                 if (msg>=0 && msg<cm_msg_num)
1477                         msgtext = cm_msg_name[msg];
1478                 PDEBUG(DEBUG_CRYPT, "EPOINT(%d) sending message '%s' (text = %s)\n", ea_endpoint->ep_serial, msgtext, text?text:"");
1479         }
1480 }
1481
1482 /* change state
1483  */
1484 void EndpointAppPBX::cryptman_state(int state)
1485 {
1486         PDEBUG(DEBUG_CRYPT, "Changing state from %s to %s\n", statename(e_crypt_state), statename(state));
1487         e_crypt_state = state;
1488 }
1489
1490
1491 /* set timeout
1492  */
1493 void EndpointAppPBX::cryptman_timeout(int secs)
1494 {
1495         if (secs) {
1496                 e_crypt_timeout_sec = now_tv.tv_sec+secs;
1497                 e_crypt_timeout_usec = now_tv.tv_usec;
1498                 PDEBUG(DEBUG_CRYPT, "Changing timeout to %d seconds\n", secs);
1499         } else {
1500                 e_crypt_timeout_sec = 0;
1501                 e_crypt_timeout_usec = 0;
1502                 PDEBUG(DEBUG_CRYPT, "turning timeout off\n", secs);
1503         }
1504 }
1505
1506 /* encode a message to be sent via b-channel
1507  */
1508 int cryptman_encode_bch(unsigned char *data, int len, unsigned char *buf, int buf_len)
1509 {
1510         unsigned int crc;
1511         int overhead = 18;
1512
1513         len--; /* without null-termination */
1514         if (buf_len < len+overhead) {
1515                 PERROR("frame too long for buffer");
1516                 return(0);
1517         }
1518         PDEBUG(DEBUG_CRYPT, "encoding a block of %d bytes.\n", len);
1519
1520         /* write identification sequence to the header */
1521         UNCPY((char *)buf, "CRYPTMAN" ,8);
1522         buf += 8;
1523         /* length + checksumme */
1524         buf[0] = len >> 8;
1525         buf[1] = len & 0xff;
1526         crc = crc32(buf, 2);
1527         buf += 2;
1528         buf[0] = crc >> 24;
1529         buf[1] = crc >> 16;
1530         buf[2] = crc >> 8;
1531         buf[3] = crc;
1532         buf += 4;
1533         /* data + checksumme */
1534         memcpy(buf, data, len);
1535         crc = crc32(buf, len);
1536         buf += len;
1537         buf[0] = crc >> 24;
1538         buf[1] = crc >> 16;
1539         buf[2] = crc >> 8;
1540         buf[3] = crc;
1541         buf += 4;
1542         return(len + overhead);
1543 }
1544         
1545 /* decode a message from b-channel
1546  */
1547 void PmISDN::cryptman_listen_bch(unsigned char *p, int l)
1548 {
1549         int i;
1550         struct lcr_msg *message;
1551
1552         retry:
1553         if (!l)
1554                 return;
1555
1556         /* check for the keyword */
1557         if (p_m_crypt_listen_state == 0) {
1558                 while((*p++)!='C' && l)
1559                         l--;
1560                 if (!l)
1561                         return;
1562                 l--;
1563                 p_m_crypt_listen_state++;
1564                 if (!l)
1565                         return;
1566         }
1567         if (p_m_crypt_listen_state < 8) {
1568                 i = p_m_crypt_listen_state;
1569                 while(i < 8) {
1570                         l--;
1571                         if (*p++ != "CRYPTMAN"[i]) {
1572                                 p_m_crypt_listen_state = 0;
1573                                 goto retry;
1574                         }
1575                         p_m_crypt_listen_state++;
1576                         if (!l)
1577                                 break;
1578                         i++;
1579                 }
1580                 if (!l)
1581                         return;
1582         }
1583         /* high byte of length */
1584         if (p_m_crypt_listen_state == 8) {
1585                 p_m_crypt_listen_len = (*p++) << 8;
1586                 p_m_crypt_listen_state++;
1587                 if (!(--l))
1588                         return;
1589         }
1590         /* low byte of length */
1591         if (p_m_crypt_listen_state == 9) {
1592                 p_m_crypt_listen_len += *p++;
1593                 p_m_crypt_listen_state++;
1594                 if (!(--l))
1595                         return;
1596         }
1597         /* crc */
1598         if (p_m_crypt_listen_state == 10) {
1599                 p_m_crypt_listen_crc = (*p++) << 24;
1600                 p_m_crypt_listen_state++;
1601                 if (!(--l))
1602                         return;
1603         }
1604         if (p_m_crypt_listen_state == 11) {
1605                 p_m_crypt_listen_crc += (*p++) << 16;
1606                 p_m_crypt_listen_state++;
1607                 if (!(--l))
1608                         return;
1609         }
1610         if (p_m_crypt_listen_state == 12) {
1611                 p_m_crypt_listen_crc += (*p++) << 8;
1612                 p_m_crypt_listen_state++;
1613                 if (!(--l))
1614                         return;
1615         }
1616         if (p_m_crypt_listen_state == 13) {
1617                 unsigned char lencheck[2];
1618                 p_m_crypt_listen_crc += *p++;
1619                 /* check for CRC */
1620                 lencheck[0] = p_m_crypt_listen_len >> 8;
1621                 lencheck[1] = p_m_crypt_listen_len & 0xff;
1622                 if (crc32(lencheck, 2) != p_m_crypt_listen_crc) {
1623                         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);
1624                         p_m_crypt_listen_state = 0;
1625                         goto retry;
1626                 }
1627                 if (p_m_crypt_listen_len > (int)sizeof(p_m_crypt_listen_msg)) {
1628                         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));
1629                         p_m_crypt_listen_state = 0;
1630                         goto retry;
1631                 }
1632                 if (!p_m_crypt_listen_len) {
1633                         PDEBUG(DEBUG_CRYPT, "PmISDN(%s) received a block of 0 bytes\n", p_name);
1634                         p_m_crypt_listen_state = 0;
1635                         goto retry;
1636                 }
1637                 p_m_crypt_listen_state++;
1638                 if (!(--l))
1639                         return;
1640         }
1641         /* read message */
1642         while (p_m_crypt_listen_state>=14 && p_m_crypt_listen_state<(p_m_crypt_listen_len+14)) {
1643                 p_m_crypt_listen_msg[p_m_crypt_listen_state-14] = *p++;
1644                 p_m_crypt_listen_state++;
1645                 if (!(--l))
1646                         return;
1647         }
1648         /* crc */
1649         if (p_m_crypt_listen_state == 14+p_m_crypt_listen_len) {
1650                 p_m_crypt_listen_crc = (*p++) << 24;
1651                 p_m_crypt_listen_state++;
1652                 if (!(--l))
1653                         return;
1654         }
1655         if (p_m_crypt_listen_state == 15+p_m_crypt_listen_len) {
1656                 p_m_crypt_listen_crc += (*p++) << 16;
1657                 p_m_crypt_listen_state++;
1658                 if (!(--l))
1659                         return;
1660         }
1661         if (p_m_crypt_listen_state == 16+p_m_crypt_listen_len) {
1662                 p_m_crypt_listen_crc += (*p++) << 8;
1663                 p_m_crypt_listen_state++;
1664                 if (!(--l))
1665                         return;
1666         }
1667         if (p_m_crypt_listen_state == 17+p_m_crypt_listen_len) {
1668                 l--;
1669                 p_m_crypt_listen_crc += *p++;
1670                 /* check for CRC */
1671                 if (crc32(p_m_crypt_listen_msg, p_m_crypt_listen_len) != p_m_crypt_listen_crc) {
1672                         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);
1673                         p_m_crypt_listen_state = 0;
1674                         if (!l)
1675                                 return;
1676                         goto retry;
1677                 }
1678                 /* now send message */
1679                 p_m_crypt_listen_state = 0;
1680                 PDEBUG(DEBUG_CRYPT, "PmISDN(%s) received a block of %d bytes sending to crypt manager\n", p_name, p_m_crypt_listen_len);
1681                 if ((int)sizeof(message->param.crypt.data) < p_m_crypt_listen_len+1) /* null-terminated */ {
1682                         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);
1683                         if (!l)
1684                                 return;
1685                         goto retry;
1686                 }
1687                 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CRYPT);
1688                 message->param.crypt.type = CR_MESSAGE_IND;
1689                 message->param.crypt.len = p_m_crypt_listen_len+1; /* null termination */
1690                 memcpy(message->param.crypt.data, p_m_crypt_listen_msg, p_m_crypt_listen_len);
1691                 message_put(message);
1692                 p_m_crypt_listen_state = 0;
1693                 if (!l)
1694                         return;
1695                 goto retry;
1696         }
1697 }
1698
1699
1700 /* encrypt call using share secret (keypad function)
1701  */
1702 void EndpointAppPBX::encrypt_shared(void)
1703 {
1704         struct lcr_msg *message;
1705         const char *errstr = "";
1706         class Port *port;
1707         int type, key_len;
1708         unsigned char *key;
1709         char *auth_pointer, *crypt_pointer, *key_pointer;
1710         int ret;
1711
1712         /* redisplay current crypt display */
1713         if (e_crypt != CRYPT_OFF) {
1714                 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) encryption in progress, so we request the current message.\n", ea_endpoint->ep_serial);
1715                 message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_join_id, EPOINT_TO_JOIN, MESSAGE_CRYPT);
1716                 message->param.crypt.type = CU_INFO_REQ;
1717                 message_put(message);
1718                 return;
1719         }
1720
1721         if (check_external(&errstr, &port)) {
1722                 reject:
1723                 message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_portlist->port_id, EPOINT_TO_PORT, MESSAGE_NOTIFY);
1724                 SCPY(message->param.notifyinfo.display, errstr);
1725                 message_put(message);
1726                 set_tone(ea_endpoint->ep_portlist, "crypt_off");
1727                 e_tone[0] = '\0';
1728                 return;
1729         }
1730
1731         /* check the key for the call */
1732         if (port->p_type==PORT_TYPE_DSS1_TE_OUT || port->p_type==PORT_TYPE_DSS1_NT_OUT)
1733                 ret = parse_secrets((char *)e_ext.number, (char *)port->p_dialinginfo.id, &auth_pointer, &crypt_pointer, &key_pointer);
1734         else {
1735                 if (!port->p_callerinfo.id[0]) {
1736                         PDEBUG(DEBUG_EPOINT, "EPOINT(%d) incoming remote call has no caller ID.\n", ea_endpoint->ep_serial);
1737                         errstr = "No Remote ID";
1738                         goto reject;
1739                 }
1740                 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);
1741         }
1742         if (!ret) {
1743                 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) Key was not found.\n", ea_endpoint->ep_serial);
1744                 errstr = "No Key";
1745                 goto reject;
1746         }
1747         key = crypt_key((unsigned char *)key_pointer, &key_len);
1748         if (!key) {
1749                 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) Key invalid.\n", ea_endpoint->ep_serial);
1750                 errstr = "Invalid Key";
1751                 goto reject;
1752         }
1753         if (key_len > 128) {
1754                 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) Key too long.\n", ea_endpoint->ep_serial);
1755                 errstr = "Key Too Long";
1756                 goto reject;
1757         }
1758         if (!!strcasecmp(auth_pointer, "manual")) {
1759                 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) Wrong authentication method.\n", ea_endpoint->ep_serial);
1760                 errstr = "Wrong Auth Type";
1761                 goto reject;
1762         }
1763         if (!strcasecmp(crypt_pointer, "blowfish")) {
1764                 type = CC_ACTBF_REQ;
1765                 if (key_len < 4) {
1766                         PDEBUG(DEBUG_EPOINT, "EPOINT(%d) Key too short.\n", ea_endpoint->ep_serial);
1767                         errstr = "Key Too Short";
1768                         goto reject;
1769                 }
1770                 if (key_len > 56) {
1771                         PDEBUG(DEBUG_EPOINT, "EPOINT(%d) Key too long.\n", ea_endpoint->ep_serial);
1772                         errstr = "Key Too Long";
1773                         goto reject;
1774                 }
1775         } else {
1776                 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) Wrong crypt method.\n", ea_endpoint->ep_serial);
1777                 errstr = "Wrong Crypt Type";
1778                 goto reject;
1779         }
1780
1781         PDEBUG(DEBUG_EPOINT, "EPOINT(%d) Key is ok, sending activation+key to cryptman.\n", ea_endpoint->ep_serial);
1782         /* setting display message and state */
1783 //      SPRINT(e_crypt_display, "Shared Key");
1784         e_crypt = CRYPT_SWAIT;
1785         /* sending activation */
1786         message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_join_id, EPOINT_TO_JOIN, MESSAGE_CRYPT);
1787         message->param.crypt.type = CU_ACTS_REQ;
1788         message->param.crypt.len = key_len;
1789         memcpy(message->param.crypt.data, key, key_len);
1790         message_put(message);
1791 }
1792
1793
1794 /* encrypt call using rsa authentication (keypad function)
1795  */
1796 void EndpointAppPBX::encrypt_keyex(void)
1797 {
1798         struct lcr_msg *message;
1799         const char *errstr = "";
1800         class Port *port;
1801
1802         /* redisplay current crypt display */
1803         if (e_crypt != CRYPT_OFF) {
1804                 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) encryption in progress, so we request the current message.\n", ea_endpoint->ep_serial);
1805                 message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_join_id, EPOINT_TO_JOIN, MESSAGE_CRYPT);
1806                 message->param.crypt.type = CU_INFO_REQ;
1807                 message_put(message);
1808                 return;
1809         }
1810
1811
1812         if (check_external(&errstr, &port)) {
1813                 message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_portlist->port_id, EPOINT_TO_PORT, MESSAGE_NOTIFY);
1814                 SCPY(message->param.notifyinfo.display, errstr);
1815                 message_put(message);
1816                 set_tone(ea_endpoint->ep_portlist, "crypt_off");
1817                 e_tone[0] = '\0';
1818                 return;
1819         }
1820
1821 #ifndef CRYPTO
1822         message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_portlist->port_id, EPOINT_TO_PORT, MESSAGE_NOTIFY);
1823         SCPY(message->param.notifyinfo.display, "Not Compiled");
1824         message_put(message);
1825         set_tone(ea_endpoint->ep_portlist, "crypt_off");
1826         e_tone[0] = '\0';
1827 #else
1828         PDEBUG(DEBUG_EPOINT, "EPOINT(%d) Sending key-exchange activation to cryptman.\n", ea_endpoint->ep_serial);
1829         /* setting display message and state */
1830 //      SPRINT(e_crypt_display, "Key-Exchange");
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, "Key-Exchange");
1833         message_put(message);
1834         e_crypt = CRYPT_KWAIT;
1835         /* sending activation */
1836         message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_join_id, EPOINT_TO_JOIN, MESSAGE_CRYPT);
1837         message->param.crypt.type = CU_ACTK_REQ;
1838         message_put(message);
1839 #endif /* CRYPTO */
1840 }
1841
1842
1843 /* turn encryption off (keypad function)
1844  */
1845 void EndpointAppPBX::encrypt_off(void)
1846 {
1847         struct lcr_msg *message;
1848
1849         if (e_crypt!=CRYPT_ON && e_crypt!=CRYPT_OFF) {
1850                 message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_portlist->port_id, EPOINT_TO_PORT, MESSAGE_NOTIFY);
1851                 SCPY(message->param.notifyinfo.display, "Please Wait");
1852                 message_put(message);
1853                 return;
1854         }
1855         if (e_crypt == CRYPT_OFF) {
1856                 message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_portlist->port_id, EPOINT_TO_PORT, MESSAGE_NOTIFY);
1857                 SCPY(message->param.notifyinfo.display, "No Encryption");
1858                 message_put(message);
1859                 set_tone(ea_endpoint->ep_portlist, "crypt_off");
1860                 e_tone[0] = '\0';
1861                 return;
1862         }
1863
1864         PDEBUG(DEBUG_EPOINT, "EPOINT(%d) Sending deactivation to cryptman.\n", ea_endpoint->ep_serial);
1865         /* setting display message and state */
1866 //      SPRINT(e_crypt_display, "Deactivating");
1867         message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_portlist->port_id, EPOINT_TO_PORT, MESSAGE_NOTIFY);
1868         SCPY(message->param.notifyinfo.display, "Deactivating");
1869         message_put(message);
1870         e_crypt = CRYPT_RELEASE;
1871         /* sending activation */
1872         message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_join_id, EPOINT_TO_JOIN, MESSAGE_CRYPT);
1873         message->param.crypt.type = CU_DACT_REQ;
1874         message_put(message);
1875 }
1876
1877
1878 /* messages from manager to endpoint
1879  */
1880 void EndpointAppPBX::encrypt_result(int msg, char *text)
1881 {
1882         struct lcr_msg *message;
1883
1884         switch(msg) {
1885                 case CU_ACTK_CONF:
1886                 case CU_ACTS_CONF:
1887                 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) encryption now active.\n", ea_endpoint->ep_serial);
1888                 set_tone(ea_endpoint->ep_portlist, "crypt_on");
1889                 e_tone[0] = '\0';
1890                 e_crypt = CRYPT_ON;
1891                 display:
1892                 if (text) if (text[0]) {
1893                         SCPY(e_crypt_info, text);
1894                         message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_portlist->port_id, EPOINT_TO_PORT, MESSAGE_NOTIFY);
1895                         SCPY(message->param.notifyinfo.display, e_crypt_info);
1896                         message_put(message);
1897                 }
1898                 break;
1899
1900                 case CU_ERROR_IND:
1901                 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) encryption error. (%s)\n", ea_endpoint->ep_serial, text);
1902                 set_tone(ea_endpoint->ep_portlist, "crypt_off");
1903                 e_tone[0] = '\0';
1904                 e_crypt = CRYPT_OFF;
1905                 goto display;
1906                 break;
1907
1908                 case CU_DACT_CONF:
1909                 case CU_DACT_IND:
1910                 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) encryption now off. (%s)\n", ea_endpoint->ep_serial, text);
1911                 set_tone(ea_endpoint->ep_portlist, "crypt_off");
1912                 e_tone[0] = '\0';
1913                 e_crypt = CRYPT_OFF;
1914                 goto display;
1915                 break;
1916
1917                 case CU_INFO_CONF:
1918                 case CU_INFO_IND:
1919                 PDEBUG(DEBUG_EPOINT, "EPOINT(%d) information. (%s)\n", ea_endpoint->ep_serial, text);
1920                 goto display;
1921                 break;
1922
1923                 default:
1924                 PERROR("EPOINT(%d) crypt manager sends us an invalid message. (type = %d)\n", ea_endpoint->ep_serial, msg);
1925         }
1926 }
1927
1928